简体   繁体   English

Haskell中函数调用的优化

[英]Optimization of Function Calls in Haskell

Not sure what exactly to google for this question, so I'll post it directly to SO: 不知道该问题到底适合谷歌搜索,所以我将其直接发布到SO:

  1. Variables in Haskell are immutable Haskell中的变量是不可变的
  2. Pure functions should result in same values for same arguments 纯函数应为相同的参数产生相同的值

From these two points it's possible to deduce that if you call somePureFunc somevar1 somevar2 in your code twice, it only makes sense to compute the value during the first call. 从这两点可以推断出,如果您在代码中两次调用somePureFunc somevar1 somevar2 ,则只有在第一次调用时计算该值才有意义。 The resulting value can be stored in some sort of a giant hash table (or something like that) and looked up during subsequent calls to the function. 结果值可以存储在某种巨型哈希表(或类似的哈希表)中,并在随后的函数调用中查找。 I have two questions: 我有两个问题:

  1. Does GHC actually do this kind of optimization? GHC是否真的进行了这种优化?
  2. If it does, what is the behaviour in the case when it's actually cheaper to repeat the computation than to look up the results? 如果是这样,那么重复计算比查找结果便宜得多的情况下会发生什么情况?

Thanks. 谢谢。

GHC doesn't do automatic memoization . GHC不会自动记忆 See the GHC FAQ on Common Subexpression Elimination (not exactly the same thing, but my guess is that the reasoning is the same) and the answer to this question . 请参阅《 GHC常见子表达式消除常见问题解答》(不完全相同,但我想原因是相同的)和该问题的答案。

If you want to do memoization yourself, then have a look at Data.MemoCombinators . 如果您想自己进行记忆,请查看Data.MemoCombinators

Another way of looking at memoization is to use laziness to take advantage of memoization. 查看记忆的另一种方法是使用惰性来利用记忆。 For example, you can define a list in terms of itself. 例如,您可以根据自身定义列表。 The definition below is an infinite list of all the Fibonacci numbers (taken from the Haskell Wiki ) 下面的定义是所有斐波那契数的无限列表(摘自Haskell Wiki

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

Because the list is realized lazily it's similar to having precomputed (memoized) previous values. 因为列表是懒惰地实现的,所以它类似于预先计算(存储)以前的值。 eg fibs !! 10 例如fibs !! 10 fibs !! 10 will create the first ten elements such that fibs 11 is much faster. fibs !! 10将创建前十个元素,以使fibs 11更快。

Saving every function call result (cf. hash consing ) is valid but can be a giant space leak and in general also slows your program down a lot. 保存每个函数调用结果(请参阅hash consing )是有效的,但可能会导致巨大的空间泄漏,并且通常还会使程序运行速度大大降低。 It often costs more to check if you have something in the table than to actually compute it. 检查表中是否有东西通常要比实际计算花费更多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM