2016-04-20 17 views

risposta

8

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.

4

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.