How to benchmark functions in Clojure?

…衆ロ難τιáo~ 提交于 2019-11-29 20:17:05

You might want to look into Hugo Duncan's benchmarking library for Clojure -- Criterium.

From the README:

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

If it's just a matter of wanting to capture the string programmatically, you can bind *out* to something else before using time.

user=> (def x (with-out-str (time (+ 2 2))))
#'user/x
user=> x
"\"Elapsed time: 0.119 msecs\"\n"

If you want more control over the format, then you can create your own version of time using Java's System time methods, which is what the time macro uses under the hood anyway:

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__)

Take that basic structure and replace the call to prn with whatever reporting mechanism you would prefer.

If you generate a Java binding for your functions (and with some Clojure Maven plugin reconfiguration), you can even use JMH (http://openjdk.java.net/projects/code-tools/jmh/) which is probably the best JVM microbenchmarking harness. Have a look at https://github.com/circlespainter/pulsar-auto-instrument-bench

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!