簡體   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