假设我有两个可以使用相同中间结果的计算。如果我编写一个命令式程序,我会将相同的(相对)“全局”状态传递给两个函数,以提高效率。
在编写函数代码时,我会使用一个计算中间值的函数作为需要该值的两个函数的一部分。我是否应该期望编译器优化该函数调用,或者是否有更智能的方法来设计程序?
为了澄清这一点,这里有一个例子。
假设我有一个函数可以在经过漫长而乏味的计算后计算某些属性a
。从 a
中,我需要计算另外两个属性 b
和 c
。例如:b = a^2
和 c = a^7 + a^(1/7)
。现在,作为主程序的一部分,我调用函数来计算 b
和 c
。查找 a
的计算会只执行一次并重复使用结果,还是会多次计算 a
?
Ps:如果相关的话,我正在学习 Haskell。
请您参考如下方法:
Suppose I have two computations which could use the same intermediate result. If I wrote an imperative program, I would pass the same (relatively) "global" state to both functions, to be more efficient.
When writing functional code, I would use a function that computes the intermediate value as part of both functions which need that value. Should I be expecting my compiler to optimize that function call, or is there a more intelligent way for me to design the program?
具体来说,您有两个函数,它们都计算相同的内容作为子计算的一部分。例如
f x = y + 3
where
y = x ^ 2
g x = y * 7
where
y = x ^ 2
z = f 2 + g 2
因此,您想要“浮出”公共(public)子表达式 x ^ 2
并共享它。
这是"common subexpression elimination" 。这是编译器可以执行的优化,或者您可以手动执行的操作。 GHC,Haskell 编译器,will do CSE in some cases 。在其他情况下,您可以通过显式命名中间计算来手动完成。
编译器这样做会更好。