【问题标题】:Concatenation order and performance under Lazy Evaluation in Haskell [duplicate]Haskell中延迟评估下的连接顺序和性能[重复]
【发布时间】:2020-06-15 08:38:38
【问题描述】:

考虑以下两个执行顺序:

a ++ (b ++ c)

(a ++ b) ++ c

为什么第一个执行顺序比第二个快?

我是 Haskell 新手,希望得到详细的解释,谢谢!

【问题讨论】:

  • 你怎么知道它更快?

标签: performance haskell concat lazy-evaluation associativity


【解决方案1】:

在充分评估x ++ y的结果时,您必须付费:

  1. 全面评估x的成本。
  2. 全面评估y 的成本。
  3. 在执行(++) 操作时遍历一次x 的成本。

现在让我们比较a ++ (b ++ c)(a ++ b) ++ c。让我们将评估a 的成本写为CA(类似CB、CC),将遍历a 的成本写为TA(类似TB、TC)。那么全面评估a ++ (b ++ c)的成本是:

  1. a, CA 的费用。
  2. b ++ c 的费用,即
    1. CB
    2. 抄送
    3. b 的一次遍历,TB。
  3. TA

这是 CA+CB+CC+TA+TB 的总和。现在,对于(a ++ b) ++ c

  1. a ++ b 的费用,即
    1. 加拿大
    2. CB
    3. TA
  2. 抄送
  3. a ++ b的一次遍历,即TA+TB。

这是 CA+CB+CC+2*TA+TB 的总和。相对于其他订单,多了一个a的遍历,需要额外的TA成本,所以这个订单比较贵。

我留给读者尝试更长的链并开始找出模式。简而言之,坏关联会在每次调用(++) 时重做所有已经完成的遍历,再加上一次,因此会产生二次遍历,而好的关联最多会遍历每个列表一次。

【讨论】:

  • 所以这可能就是为什么++infixr 而不是infixl
  • @MikaelF 是的,确实如此。
猜你喜欢
  • 1970-01-01
  • 2016-09-12
  • 1970-01-01
  • 2021-08-13
  • 2012-06-13
  • 1970-01-01
  • 1970-01-01
  • 2011-03-03
  • 1970-01-01
相关资源
最近更新 更多