2014-01-03 6 views
9

Я хотел сделать рендеринг графики в реальном времени и пытался выполнить несколько расчетов на пиксель за кадр. Затем я быстро заметил, что это было очень медленно и началось с самой базы: как быстро я могу перебирать все пиксели?Clojure performance: REPL versus uberjar

Я нашел DOTIMES достаточно быстро, но когда я делаю это в РЕПЛ это ужасно медленно:

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

Тогда я положил это в проект Leiningen. Когда я делаю «лейн-бег», он так же медленный. Но когда я создаю uberjar и запустить его с помощью команды Java это намного быстрее:

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

Хотя первый запуск еще много медленнее. В чем разница? В обоих случаях код компилируется, нет интерпретируемого Clojure, не так ли? Это JIT, некоторые оптимизации или некоторые специальные параметры JVM, которые установлены для REPL?

Спасибо за любые идеи.

+1

Я не могу воспроизвести медленность REPL. Какая у вас настройка? –

ответ

9

Leiningen запускает JVM с определенными настройками по умолчанию, которые улучшают время запуска, но ухудшают производительность во время выполнения. Итак, вы можете снова проверить с :jvm-opts ^:replace [], добавленным к вашему project.clj.


Помимо этого, в то время как ниже не добавляет ничего в пути объяснения синхронизации несоответствия между РЕПЛ и überjar, я думал, что комментировать бенчмаркинг в случае, если вы заботитесь о точных результатах:

time не является хорошим инструментом для бенчмаркинга с dotimes или нет. (Нет dotimes - ЛТ-компилятор не будет удар в, с dotimes - это, вероятно, будет, но вполне может решить, что тело цикла является Noop и оптимизировать его прочь полностью.)

Hugo Дункана Criterium является надежное решение Clojure, которое заботится о разминке JIT, зацикливая таким образом, что не будет оптимизировано и статистическая обработка результатов. Простой критериум тест может выглядеть следующим образом:

(require '[criterium.core :as c]) 

(def v [0 1 2]) 

(c/bench (nth v 0)) 

(Это измеряет время, чтобы получить доступ к начальному элементу короткого вектора, состоявшемуся в Var я бы ожидать (+ 1 1) в конце концов, будет составлен к постоянная, так там. не может быть ничего не оставлено для сравнения.)

+1

Я предполагаю, что это действительно были варианты JVM, настройка: jvm-opts в проекте. Теперь я получаю такую ​​же производительность для REPL. Благодарю. – anselm

+0

Кажется, это связано с параметрами TieredCompilation JVM. Если я устанавливаю те же опции, что и Leiningen при запуске JAR вручную, он также становится очень медленным. – anselm

Смежные вопросы