Как тестировать функции в 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

Другие вопросы по тегам