2012-07-04 15 views
14

Oto definicja Clojure z dnia vector:Dlaczego implementacja `vector` ma wiele przypadków?

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

Dlaczego jest tak wiele przypadków? Lub, jeśli jest ich tak wiele, dlaczego nie ma ich więcej?

Zgaduję, że to balansuje pomiędzy efektywnością realizacji i prawdopodobieństwem, ale nie do końca rozumiem, jak byłoby to skuteczniejsze.

Odpowiedz

22

4 wydaje się zachowywać równowagę między wydajnością, gdy występuje wiele argumentów i gdy nie ma wielu argumentów.

Jako przykład:

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

Prowadzenie testu z 4 elementów:

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

a następnie 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" 

I z 8 (to wszystkie funkcje używają sprawy 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" 
Powiązane problemy