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