使用列表或向量,我的Clojure功能可能会非常慢吗?

时间:2012-01-16 21:40:55

标签: performance data-structures clojure

我刚刚学习Clojure,我刚刚写了这个函数:

(defn replace-last [coll value]
    (assoc coll (dec (count coll)) value))

我只是担心列表和/或向量可能会非常慢 - 我只是不了解它们还不知道。

谢谢!

2 个答案:

答案 0 :(得分:11)

对于向量,这将非常快 - 向量的一个承诺是快速创建略微修改的副本。

对于列表,这根本不起作用 - 它们不是关联的(clojure.lang.Associative),因此不是assoc的有效参数。至于其他可能的方法,如果你需要获得一个实际的列表(而不是seq(能)),你运气不好 - 访问/替换列表的最后一个元素基本上是一个线性时间操作。另一方面,如果你可以使用懒惰的seq,它看起来像你的列表,除了最后的元素,你可以实现butlast的半惰性变体({{1}中的那个) }根本不是懒惰的,并将其用于clojure.core

lazy-cat

这会延迟替换最终元素,直到你实际接近它消耗你的seq。

示例互动:

(defn semi-lazy-butlast [s]
  (cond (empty? s) s
        (empty? (next s)) nil ; or perhaps ()
        :else (lazy-seq (cons (first s)
                              (semi-lazy-butlast (next s))))))

(defn replace-last [s x]
  (if (empty? s) ; do nothing if there is no last element to replace
    s
    (lazy-cat (semi-lazy-butlast s) [x])))

答案 1 :(得分:3)

对于向量,这将与其他任何内容一样快,并且对列表不起作用。