考虑一下这个功能:
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
如果确实如此,那么哪个级别设置允许呢? 如果没有,那么为什么呢? 在这种情况下内存废物不能作为解释的理由这个答案 ,因为引入变量被尽快函数执行完毕释放。
请注意,这不是重复这个问题 ,因为当地的范围,因此可能会得到完全不同的答案。
GHC现在确实在默认情况下一些CSE ,作为-fcse
标志上。
在默认情况下启用..常见的子表达式消除优化。 如果你有你不想共位,一些unsafePerformIO表达式转换这一关可能是有用的。
然而,这是保守的 ,由于与导入共享(并且因此空间泄漏)的问题。 该CSE通是得到一个好一点 ,但(与此 )。
最后,注意,全CSE插件。
- http://hackage.haskell.org/package/cse-ghc-plugin
如果你有一些代码,可以从中获益。
即使在这样的本地设置,它仍然是它并不明显,引入共享始终是一个最优化的情况下。 考虑下面这个例子定义
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
已经减少。
你所描述的情况有更多的是与共同的子表达式消除比记忆化,但它似乎GHC目前没有做,要么是因为意外的共享可能导致内存泄露。
文章来源: Does Haskell optimizer utilize memoization for repeated function calls in a scope?