Skip to main content
 首页 » 编程设计

haskell之在功能程序中优化使用中间结果

2025年05月04日24cmt

假设我有两个可以使用相同中间结果的计算。如果我编写一个命令式程序,我会将相同的(相对)“全局”状态传递给两个函数,以提高效率。

在编写函数代码时,我会使用一个计算中间值的函数作为需要该值的两个函数的一部分。我是否应该期望编译器优化该函数调用,或者是否有更智能的方法来设计程序?

为了澄清这一点,这里有一个例子。

假设我有一个函数可以在经过漫长而乏味的计算后计算某些属性a。从 a 中,我需要计算另外两个属性 bc。例如:b = a^2c = a^7 + a^(1/7)。现在,作为主程序的一部分,我调用函数来计算 bc。查找 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 。在其他情况下,您可以通过显式命名中间计算来手动完成。

编译器这样做会更好。