Clojure: Warum ist Aget so langsam?
Nach meinem Dafürhalten haben Clojure-Vektoren im Vergleich zu Java-Arrays einen leichten Leistungseinbruch. Aus diesem Grund dachte ich, dass "konventionelle Weisheit" für die leistungskritischen Teile Ihres Codes besser geeignet ist, Java-Arrays zu verwenden.
Meine Tests legen jedoch nahe, dass dies nicht zutrifft:
<code>Clojure 1.3.0 user=> (def x (vec (range 100000))) #'user/x user=> (def xa (int-array x)) #'user/xa user=> (time (loop [i 0 s 0] (if (< i 100000) (recur (inc i) (+ s (nth x i))) s))) "Elapsed time: 16.551 msecs" 4999950000 user=> (time (loop [i 0 s 0] (if (< i 100000) (recur (inc i) (+ s (aget xa i))) s))) "Elapsed time: 1271.804 msecs" 4999950000 </code>
Wie Sie sehen können, fügt das Aget dieser Addition etwa 800% Zeit hinzu. Beide Methoden sind immer noch viel langsamer als Java:
<code>public class Test { public static void main (String[] args) { int[] x = new int[100000]; for (int i=0;i<100000;i++) { x[i]=i; } long s=0; long end, start = System.nanoTime(); for (int i=0;i<100000;i++) { s+= x[i]; } end = System.nanoTime(); System.out.println((end-start)/1000000.0+" ms"); System.out.println(s); } } > java Test 1.884 ms 4999950000 </code>
Sollte ich also zu dem Schluss kommen, dass aget 80-mal langsamer als n ist und ungefähr 800-mal langsamer als der [] -Zugriff in Java?