是否哈斯克尔优化利用在一个范围内重复函数调用记忆化?(Does Haskell optimizer

2019-07-20 13:45发布

考虑一下这个功能:

f as = if length as > 100 then length as else 100

由于该功能是纯很明显,长度将在这两个调用相同。 我的问题是不哈斯克尔优化转码以上成以下的相同呢?

f as = 
  let l = length as
  in if l > 100 then l else 100

如果确实如此,那么哪个级别设置允许呢? 如果没有,那么为什么呢? 在这种情况下内存废物不能作为解释的理由这个答案 ,因为引入变量被尽快函数执行完毕释放。


请注意,这不是重复这个问题 ,因为当地的范围,因此可能会得到完全不同的答案。

Answer 1:

GHC现在确实在默认情况下一些CSE ,作为-fcse标志上。

在默认情况下启用..常见的子表达式消除优化。 如果你有你不想共位,一些unsafePerformIO表达式转换这一关可能是有用的。

然而,这是保守的 ,由于与导入共享(并且因此空间泄漏)的问题。 该CSE通是得到一个好一点 ,但(与此 )。

最后,注意,全CSE插件。

  • http://hackage.haskell.org/package/cse-ghc-plugin

如果你有一些代码,可以从中获益。



Answer 2:

即使在这样的本地设置,它仍然是它并不明显,引入共享始终是一个最优化的情况下。 考虑下面这个例子定义

f = if length [1 .. 1000000] > 0 then head [1 .. 1000000] else 0

与这一个

f = let xs = [1 .. 1000000] in if length xs > 0 then head xs else 0

你会发现,在这种情况下,首先表现要好得多,因为每一个在名单上进行的运算的便宜,而第二个版本会导致完全凭记忆来展开列表length ,它只能是后被丢弃head已经减少。



Answer 3:

你所描述的情况有更多的是与共同的子表达式消除比记忆化,但它似乎GHC目前没有做,要么是因为意外的共享可能导致内存泄露。



文章来源: Does Haskell optimizer utilize memoization for repeated function calls in a scope?