Foldl 与 Foldr 内存使用情况
Foldl vs Foldr memory usage
给定斐波那契无限列表
fibo a b = a : fibo b (a+b)
并给出以下两个调用:
foldl (+) 1 (take 1000000 $ fibo 1 1)
foldr (+) 1 (take 1000000 $ fibo 1 1)
我预计第一个 (foldl) 会因为 thunk 分配大量内存,而事实就是这样。
然而,我没想到第二个也是如此。由于 foldr 的定义方式,我认为通常会对 (+) 的正确参数执行评估之类的堆栈(因为它的严格性)。
实际上,即使在这种情况下,我也分配了大量内存。
发生了什么事?
foldr f z xs
在 f
对其第二个参数(如 (+)
)严格时效率低下,因为它的计算结果为
f1 x1 (f x2 (f x3 ...
直到列表的最后才能开始计算。如果 f
对第二个参数不严格,则评估可以更早开始。
给定斐波那契无限列表
fibo a b = a : fibo b (a+b)
并给出以下两个调用:
foldl (+) 1 (take 1000000 $ fibo 1 1)
foldr (+) 1 (take 1000000 $ fibo 1 1)
我预计第一个 (foldl) 会因为 thunk 分配大量内存,而事实就是这样。
然而,我没想到第二个也是如此。由于 foldr 的定义方式,我认为通常会对 (+) 的正确参数执行评估之类的堆栈(因为它的严格性)。
实际上,即使在这种情况下,我也分配了大量内存。
发生了什么事?
foldr f z xs
在 f
对其第二个参数(如 (+)
)严格时效率低下,因为它的计算结果为
f1 x1 (f x2 (f x3 ...
直到列表的最后才能开始计算。如果 f
对第二个参数不严格,则评估可以更早开始。