2012-07-04 5 views
14

Hier Definition des clojure von vector:Warum hat die Vektorimplementierung mehrere Fälle?

(defn vector 
    "Creates a new vector containing the args." 
    {:added "1.0" 
    :static true} 
    ([] []) 
    ([a] [a]) 
    ([a b] [a b]) 
    ([a b c] [a b c]) 
    ([a b c d] [a b c d]) 
    ([a b c d & args] 
    (. clojure.lang.LazilyPersistentVector (create (cons a (cons b (cons c (cons d args)))))))) 

Warum gibt es so viele Fälle? Oder, wenn es so viele gibt, warum gibt es nicht mehr?

Meine Vermutung ist, dass es ein Gleichgewicht zwischen Implementierungseffizienz und Wahrscheinlichkeit trifft, aber ich sehe nicht wirklich, wie dies effizienter wäre.

Antwort

22

4 scheint ein Gleichgewicht der Effizienz zwischen, wenn es viele Argumente gibt und wenn es nicht viele Argumente gibt.

Als Beispiel:

(defn vector-few 
    ([] []) 
    ([ & args ] (. clojure.lang.LazilyPersistentVector (create args)))) 


(defn vector-many 
    ([] []) 
    ([a] [a]) 
    ([a b] [a b]) 
    ([a b c] [a b c]) 
    ([a b c d] [a b c d]) 
    ([a b c d e] [a b c d e]) 
    ([a b c d e f] [a b c d e f]) 
    ([a b c d e f & args] (. clojure.lang.LazilyPersistentVector (create (cons a (cons b (cons c (cons d (cons e (cons f args)))))))))) 

einen Test mit 4 Elementen Laufen:

=> (time (dotimes [x 1000000] (vector 1 2 3 4))) 
"Elapsed time: 12.082104 msecs" 

=> (time (dotimes [x 1000000] (vector-few 1 2 3 4))) 
"Elapsed time: 443.056339 msecs" 

=> (time (dotimes [x 1000000] (vector-many 1 2 3 4))) 
"Elapsed time: 11.812106 msecs" 

und dann mit 5:

=> (time (dotimes [x 1000000] (vector 1 2 3 4 5))) 
"Elapsed time: 467.904979 msecs" 

=> (time (dotimes [x 1000000] (vector-few 1 2 3 4 5))) 
"Elapsed time: 537.080198 msecs" 

=> (time (dotimes [x 1000000] (vector-many 1 2 3 4 5))) 
"Elapsed time: 10.30695 msecs" 

Und mit 8 (so alle Funktionen verwenden den var-args-Fall):

=> (time (dotimes [x 1000000] (vector 1 2 3 4 5 6 7 8))) 
"Elapsed time: 832.803266 msecs" 

=> (time (dotimes [x 1000000] (vector-few 1 2 3 4 5 6 7 8))) 
"Elapsed time: 689.526288 msecs" 

=> (time (dotimes [x 1000000] (vector-many 1 2 3 4 5 6 7 8))) 
"Elapsed time: 905.95839 msecs" 
Verwandte Themen