Clojure中的 butlast drop-last 有什么区别?

只是懒惰吗?我应该优先选择另一个吗?

最佳答案

同样,如果您需要实现整个集合,则butlast的速度会大大提高,如果查看其来源,这是合乎逻辑的:

(def
 butlast (fn ^:static butlast [s]
           (loop [ret [] s s]
             (if (next s)
               (recur (conj ret (first s)) (next s))
               (seq ret)))))

(defn drop-last
  ([s] (drop-last 1 s))
  ([n s] (map (fn [x _] x) s (drop n s))))

因此drop-last使用map,而butlast使用recur进行简单迭代。这是一个小例子:
user> (time (let [_ (butlast (range 10000000))]))
"Elapsed time: 2052.853726 msecs"
nil

user> (time (let [_ (doall (drop-last (range 10000000)))]))
"Elapsed time: 14072.259077 msecs"
nil

所以我不会盲目地喜欢一个。仅当我真的需要懒惰时才使用drop-last,否则才使用butlast

10-08 12:46