关于基准测试:如何在Clojure中对功能进行基准测试?

How to benchmark functions in Clojure?

我知道我可以获得时间评估功能,可以使用时间功能/宏在屏幕/标准输出上打印出来。

time宏返回被求值函数的值,因此非常适合内联使用。 但是我想在特定情况下自动测量运行时间。

是否有一个函数可以返回某个库中的经过时间以帮助进行基准测试?


如果只是想以编程方式捕获字符串,可以在使用时间之前将* out *绑定到其他对象。

1
2
3
4
5
user=> (def x (with-out-str (time (+ 2 2))))
#'user/x
user=> x
""Elapsed time: 0.119 msecs"
"

如果要对格式进行更多控制,则可以使用Java的System time方法创建自己的时间版本,无论如何,这是时间宏在后台使用的方式:

1
2
3
4
5
6
7
8
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的调用。


您可能想看看Hugo Duncan的Clojure-Criterium基准测试库。

从自述文件:

Criterium measures the computation time of an expression. It is designed to address some of the pitfalls of benchmarking, and benchmarking on the JVM in particular.

This includes:

  • statistical processing of multiple evaluations
  • inclusion of a warm-up period, designed to allow the JIT compiler to optimise its code
  • purging of gc before testing, to isolate timings from GC state prior to testing
  • a final forced GC after testing to estimate impact of cleanup on the timing results


如果您为函数生成Java绑定(并使用一些Clojure Maven插件重新配置),则甚至可以使用JMH(http://openjdk.java.net/projects/code-tools/jmh/),这可能是最好的JVM。 微标线束。 看看https://github.com/circlespainter/pulsar-auto-instrument-bench