【问题标题】:Sudden slowdown with lazy sequence惰性序列突然减速
【发布时间】:2012-04-13 02:39:34
【问题描述】:

我有这个代码:

:history
(cons [t (:latest thing)] (take n (:history thing)) )

这是为了在我的程序的每次迭代中将最近历史的滚动窗口添加到地图中。我发现,经过一定次数的迭代(约 50 次)后,我的程序会显着且渐进地变慢。

然而,如果我将代码更改为:

:history
(cons [t (:latest thing)] (take n (vec (:history thing))) )

然后程序在每次迭代中运行的时间稍长(因为正在实现惰性序列),但运行一致并且没有减慢。

刚接触 Clojure,我不明白……这与分块序列有关吗?

【问题讨论】:

    标签: performance clojure lazy-sequences


    【解决方案1】:

    我认为程序减速的意思是说“由于您的第一个代码示例执行的可能不利操作,随着序列变大,此惰性序列的消耗会减慢”。这是因为当你使用像 cons 这样的惰性操作符构建一个惰性序列时,它会创建一个操作链(函数)来生成序列,并且每次你使用这个惰性序列时都会执行这个操作链,例如:50 个 cons 操作将创建 50 个链式函数调用,每次使用序列时都会执行该函数调用,这显然比使用 50 个元素的向量并使用它要慢。

    在您的第二种情况下,惰性序列将只有 1 个操作(即缺点),其余的将从已经实现的向量中进行操作(即向量调用)

    【讨论】:

    • 好的,我知道为什么第一种情况不好,但为什么只有在达到一定数量的迭代时才会减速?是因为卡盘序列吗?
    • 实际上,现在我很困惑,第一种情况不好吗?每次我使用序列时都会执行所有这些嵌套的 cons 操作吗?当然,既然我每次都取 n ,那么序列只包含那些 n 项。它在另一个方面不好的,那就是无论如何这样做都是一种浪费的方式——我应该把剩下的和 conjing 或其他东西拿走,所以我不需要那些 n 次迭代。跨度>
    猜你喜欢
    • 2012-05-20
    • 1970-01-01
    • 1970-01-01
    • 2014-11-10
    • 2016-09-19
    • 2011-02-11
    • 1970-01-01
    • 2012-03-01
    • 2011-07-21
    相关资源
    最近更新 更多