【问题标题】:Foldl vs Foldr memory usageFoldl 与 Foldr 内存使用情况
【发布时间】:2018-12-04 20:04:17
【问题描述】:

给定斐波那契无限列表

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 是如何定义的,我认为对于 (+) 的正确参数(因为它的严格性)会执行一个通常的堆栈之类的评估。

实际上,即使在这种情况下,我也分配了大量内存。

发生了什么?

【问题讨论】:

  • 高效完成特定任务的最佳函数是foldl'可能使用foldr 有效地做到这一点,但只能以一种有点扭曲的方式:foldr (\x r acc -> r $! x + acc) id (take ...) 1

标签: haskell fold


【解决方案1】:

f 对其第二个参数(如(+))严格时,foldr f z xs 效率低下,因为它的计算结果为

f1 x1 (f x2 (f x3 ...

直到列表的最后才能开始评估。如果f 对第二个参数不严格,则评估可以更早开始。

【讨论】:

    猜你喜欢
    • 2010-09-27
    • 2011-09-04
    • 2016-09-04
    • 2011-08-28
    • 2015-01-08
    • 1970-01-01
    • 2018-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多