Rendimiento de Clojure: REPL versus uberjar

Quería hacer una representación gráfica en tiempo real y estaba tratando de hacer múltiples cálculos por píxel por fotograma. Entonces rápidamente noté que esto era muy lento y comenzó en la misma base: ¿qué tan rápido puedo recorrer todos los píxeles?

Encontré a los tiempos razonablemente rápidos, pero cuando hago esto en un REPL es muy lento:

user=> (dotimes [_ 10] (time (dotimes [_ 1e7] (+ 1 1))))
"Elapsed time: 409.177477 msecs"
"Elapsed time: 417.755502 msecs"
"Elapsed time: 418.939182 msecs"
"Elapsed time: 420.131575 msecs"
"Elapsed time: 419.83529 msecs"
"Elapsed time: 417.612003 msecs"
"Elapsed time: 420.749229 msecs"
"Elapsed time: 418.918554 msecs"
"Elapsed time: 414.403957 msecs"
"Elapsed time: 417.729624 msecs"
nil
user=>

Luego puse esto en un proyecto de Leiningen. Cuando hago una "carrera lein" es igual de lento. Pero cuando creo el uberjar y lo ejecuto con el comando java es mucho más rápido:

% java -jar target/looping-0.1.0-SNAPSHOT-standalone.jar 
"Elapsed time: 122.006758 msecs"
"Elapsed time: 3.667653 msecs"
"Elapsed time: 3.60515 msecs"
"Elapsed time: 4.008436 msecs"
"Elapsed time: 3.961558 msecs"
"Elapsed time: 3.60212 msecs"
"Elapsed time: 3.592532 msecs"
"Elapsed time: 4.573949 msecs"
"Elapsed time: 3.959568 msecs"
"Elapsed time: 3.607495 msecs"

Aunque la primera carrera sigue siendo mucho más lenta. ¿Cuál es la diferencia? En ambos casos, el código se compila, no hay Clojure interpretado, ¿verdad? ¿Es JIT, algunas optimizaciones o algunas opciones especiales de JVM que están configuradas para el REPL?

Gracias por cualquier idea.

Respuestas a la pregunta(1)

Su respuesta a la pregunta