Qual è la differenza tra butlast
e drop-last
in Clojure?Clojure butlast vs drop-last
È solo la pigrizia? Dovrei preferire uno rispetto all'altro?
Qual è la differenza tra butlast
e drop-last
in Clojure?Clojure butlast vs drop-last
È solo la pigrizia? Dovrei preferire uno rispetto all'altro?
anche, se avete bisogno di realizzare l'intera collezione, butlast
è drammaticamente più veloce, che è logico se si guarda alla fonte:
(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))))
così drop-last
utilizza map
, mentre butlast
utilizza semplici iterazione con recur
. Ecco un piccolo esempio:
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
quindi non preferirei ciecamente uno su un altro. Io uso drop-last
solo quando ho davvero bisogno di pigrizia, altrimenti butlast
.
Sì, la pigrizia, nonché il fatto che drop-last
può richiedere anche prendere n
, che indica il numero di elementi da rilasciare alla fine pigramente.
C'è una discussione here dove qualcuno sta facendo il caso che butlast
è più leggibile e forse un linguaggio familiare per i programmatori Lisp, ma io generalmente solo scegliere di utilizzare drop-last
.