假设我有两个可以使用相同中间结果的计算。如果我写了一个命令式程序,我会将相同的(相对)“全局”状态传递给两个函数,以提高效率。
在编写功能代码时,我会使用一个函数来计算中间值,作为需要该值的两个函数的一部分。我应该期待我的编译器优化该函数调用,还是有更聪明的方式来设计程序?
澄清一下,这是一个例子。
假设我有一个函数在经过漫长而乏味的计算之后计算一些属性a
。从a
开始,我需要计算其他两个属性b
和c
。例如:b = a^2
和c = a^7 + a^(1/7)
。现在,作为主程序的一部分,我调用函数来计算b
和c
。查找a
的计算是否只进行一次并重复使用,或者a
会多次计算?
Ps:如果相关,我正在学习Haskell。
答案 0 :(得分:3)
假设我有两个可以使用相同中间结果的计算。如果我写了一个命令式的程序,我会传递相同的(相对)"全球"陈述两种功能,以提高效率。
在编写功能代码时,我会使用一个函数来计算中间值,作为需要该值的两个函数的一部分。我应该期待我的编译器优化该函数调用,还是有更聪明的方式来设计程序?
所以具体来说,你有两个函数,它们都作为子计算的一部分计算相同的东西。 E.g。
f x = y + 3
where
y = x ^ 2
g x = y * 7
where
y = x ^ 2
z = f 2 + g 2
所以你想"漂浮"公共子表达式x ^ 2
,并分享它。
这是"common subexpression elimination"。这是编译器可以执行的优化,或者您可以手动完成的任务。 GHC,一个Haskell编译器,will do CSE in some cases。在其他情况下,您可以通过明确命名中间计算来手动完成。
当编译器执行它时,它会更好。