Haskell中函数调用的优化

时间:2011-05-22 08:27:45

标签: optimization haskell ghc memoization referential-transparency

不确定谷歌究竟要解决这个问题,所以我会直接发布到SO:

  1. Haskell中的变量是不可变的
  2. 纯函数应该为相同的参数产生相同的值
  3. 从这两点可以推断,如果你在代码中调用somePureFunc somevar1 somevar2两次,那么在第一次调用期间计算值是有意义的。结果值可以存储在某种巨型哈希表(或类似的东西)中,并在后续调用函数时查找。我有两个问题:

    1. GHC实际上是否进行了这种优化?
    2. 如果确实如此,那么重复计算实际上比查找结果更便宜的情况是什么?
    3. 感谢。

2 个答案:

答案 0 :(得分:16)

GHC不会自动memoization。请参阅Common Subexpression Elimination上的GHC常见问题解答(不完全相同,但我的猜测是推理相同)和this question的答案。

如果您想自己做备忘录,请查看Data.MemoCombinators

另一种查看记忆的方法是使用懒惰来利用记忆。例如,您可以根据自身定义列表。下面的定义是所有斐波纳契数的无限列表(取自Haskell Wiki

fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

因为列表是懒惰地实现的,所以类似于预先计算(memoized)的先前值。例如fibs !! 10将创建前十个元素,使fibs 11更快。

答案 1 :(得分:5)

保存每个函数调用结果(参见hash consing)是有效的,但可能是一个巨大的空间泄漏,并且通常也会使程序速度降低很多。检查表中是否有某些东西比实际计算它要花费更多。