Как измерить функции в Clojure?
Я знаю, что могу получить время, чтобы оценить функцию, которую можно распечатать на экране /stdout, используя функцию времени/макрос.
Макрос времени возвращает значение оцениваемой функции, что делает его полезным использовать его в строке. Однако я хочу автоматически измерять время выполнения при определенных обстоятельствах.
Есть ли функция, которая возвращает прошедшее время в какой-либо библиотеке, чтобы помочь с этим эталонным тестированием?
Ответы
Ответ 1
Возможно, вы захотите изучить библиотеку бенчмаркинга Hugo Duncan для Clojure - Criterium.
Из README:
Критерий измеряет время вычисления выражения. Он предназначен для решения некоторых проблем, связанных с бенчмаркингом и бенчмаркингом в JVM в частности.
Это включает в себя:
- статистическая обработка нескольких оценок
- включение периода прогрева, предназначенного для того, чтобы компилятор JIT мог оптимизировать свой код.
- очистка gc перед тестированием, чтобы изолировать тайминги от состояния GC до тестирования
- окончательный принудительный GC после тестирования для оценки воздействия очистки на результаты синхронизации
Ответ 2
Если вы хотите просто программно записать строку, вы можете привязать * out * к чему-то еще, прежде чем использовать время.
user=> (def x (with-out-str (time (+ 2 2))))
#'user/x
user=> x
"\"Elapsed time: 0.119 msecs\"\n"
Если вам нужен больше контроля над форматом, вы можете создать свою собственную версию времени, используя методы Java System time, что и макрос времени использует под капотом:
user => (macroexpand '(time (+ 2 2)))
(let* [start__4197__auto__ (. java.lang.System (clojure.core/nanoTime))
ret__4198__auto__ (+ 2 2)]
(clojure.core/prn (clojure.core/str "Elapsed time: " (clojure.core//
(clojure.core/double
(clojure.core/- (. java.lang.System (clojure.core/nanoTime))
start__4197__auto__)) 1000000.0) " msecs"))
ret__4198__auto__)
Возьмите эту базовую структуру и замените вызов prn на любой механизм отчетности, который вы предпочитаете.
Ответ 3
Если вы создаете привязку Java для своих функций (и с некоторой реконфигурацией плагина Clojure Maven), вы можете даже использовать JMH (http://openjdk.java.net/projects/code-tools/jmh/), который, вероятно, является лучшим жгутом для микрообъектива JVM. Посмотрите https://github.com/circlespainter/pulsar-auto-instrument-bench