Как тестировать функции в Clojure?
Я знаю, что могу получить время, необходимое для оценки функции, можно распечатать на экране / выводе, используя функцию времени / макрос.
Макрос времени возвращает значение вычисляемой функции, что делает его полезным для использования внутри строки. Однако я хочу автоматически измерить время выполнения при определенных обстоятельствах.
Есть ли функция, которая возвращает затраченное время в какой-то библиотеке, чтобы помочь с этим сравнением?
3 ответа
Возможно, вы захотите заглянуть в библиотеку Хьюго Дункана по тестированию Clojure - Criterium.
Из README:
Критерий измеряет время вычисления выражения. Он предназначен для решения некоторых проблем, связанных с сравнительным анализом и, в частности, сравнением с JVM.
Это включает:
- статистическая обработка множественных оценок
- включение периода прогрева, предназначенного для того, чтобы компилятор JIT мог оптимизировать свой код
- очистка gc перед тестированием, чтобы изолировать время от состояния GC перед тестированием
- окончательный принудительный сбор данных после тестирования, чтобы оценить влияние очистки на результаты синхронизации
Если вам нужно просто захватить строку программно, вы можете связать *out* с чем-то другим, прежде чем использовать время.
user=> (def x (with-out-str (time (+ 2 2))))
#'user/x
user=> x
"\"Elapsed time: 0.119 msecs\"\n"
Если вам нужен больший контроль над форматом, то вы можете создать свою собственную версию времени, используя методы системного времени Java, которые в любом случае использует макрос времени:
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 тем механизмом отчетности, который вы предпочитаете.
Если вы сгенерируете Java-привязку для своих функций (и с некоторой реконфигурацией плагина Clojure Maven), вы даже можете использовать JMH ( http://openjdk.java.net/projects/code-tools/jmh/), который, вероятно, является лучшей JVM жгут для микробенчмаркинга. Посмотрите на https://github.com/circlespainter/pulsar-auto-instrument-bench