繁体   English   中英

Haskell - foldl'在折叠和性能问题方面

[英]Haskell - foldl' in terms of foldr and performance issues

在使用fold 的普遍性和表现力的教程深入研究fold ,我发现了使用foldrfoldl的惊人定义:

-- I used one lambda function inside another only to improve reading
foldl :: (b -> a -> b) -> b -> [a] -> b
foldl f z xs = foldr (\x g -> (\a -> g (f a x))) id xs z

在了解了正在发生的事情之后,我想我甚至可以使用foldr来定义foldl' ,这将是这样的:

foldl' :: (b -> a -> b) -> b -> [a] -> b
foldl' f z xs = foldr (\x g -> (\a -> let z' = a `f` x in z' `seq` g z')) id xs z

这与此平行:

foldl' :: (b -> a -> b) -> b -> [a] -> b
foldl' f z (x:xs) = let z' = z `f` x 
                    in seq z' $ foldl' f z' xs 
foldl' _ z _     = z

在这样的简单情况下,它们似乎都在恒定的空间(不创建thunk)中运行:

*Main> foldl' (+) 0 [1..1000000]
500000500000

我可以考虑foldl'在性能方面的两种定义吗?

在GHC 7.10+中, foldlfoldl'都是根据foldr定义的。 他们之前没有的原因是GHC没有足够好地优化foldr定义以参与foldr/build fusion。 但GHC 7.10引入了一种新的优化,特别是允许foldr/build融合成功,同时使用这种方式定义的foldl'foldl'

这里的最大胜利是像foldl' (+) 0 [1..10]这样的表达式可以优化到永远不会分配一个(:)构造函数。 我们都知道,绝对最快的垃圾收集是在没有垃圾收集的时候。

有关GHC 7.10中新优化的信息,以及为什么有必要,请参见http://www.joachim-breitner.de/publications/CallArity-TFP.pdf

暂无
暂无

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

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