2012-07-04 21 views
14

Aquí es la definición de clojure de vector:¿Por qué la implementación de `vector` tiene múltiples casos?

(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)))))))) 

¿Por qué hay tantos casos? O, si hay tantos, ¿por qué no hay más?

Supongo que se está logrando un equilibrio entre la eficiencia de la implementación y la probabilidad, pero no veo muy bien cómo sería esto más eficiente.

Respuesta

22

4 parece lograr un equilibrio de eficiencia entre cuando hay muchos argumentos y cuando no hay muchos argumentos.

Como un ejemplo:

(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)))))))))) 

Ejecución de una prueba con 4 elementos:

=> (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" 

Y luego con 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" 

Y con 8 (para todas las funciones están usando el caso var-args):

=> (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" 
Cuestiones relacionadas