Clojure: por que o aget é tão lento?

Na minha opinião, os vetores clojure têm um pequeno impacto no desempenho em comparação com os arrays java. Como resultado, achei que a "sabedoria convencional" era que, para as partes críticas do desempenho do seu código, seria melhor usar matrizes java.

Meus testes, no entanto, sugerem que isso não é verdade:

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

Como você pode ver, o aget adiciona cerca de 800% de tempo a esta adição. Ambos os métodos ainda são muito mais lentos que o java nativo:

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

Então, a minha conclusão é que o aget é 80 vezes mais lento que o nth, e cerca de 800 vezes mais lento que o [] -access em java?

questionAnswers(3)

yourAnswerToTheQuestion