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

Pet*_*ans 40 benchmarking clojure

我知道我可以花时间来评估一个功能,可以使用时间函数/宏在屏幕/标准输出上打印出来.

时间宏返回已计算函数的值,这使得内联使用它非常棒.但是我想在特定情况下自动测量运行时.

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

G__*_*G__ 31

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

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

如果您想要更多地控制格式,那么您可以使用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__)
Run Code Online (Sandbox Code Playgroud)

采用这种基本结构,用你喜欢的任何报告机制替换对prn的调用.

  • +1使用macroexpand挖掘引擎盖! (4认同)

Mic*_*zyk 27

你可能想看看Hugo Duncan的Clojure基准测试库 - Criterium.

来自README:

Criterium测量表达式的计算时间.它旨在解决基准测试的一些缺陷,特别是对JVM进行基准测试.

这包括:

  • 多个评估的统计处理
  • 包含一个预热期,旨在允许JIT编译器优化其代码
  • 在测试之前清除gc,以在测试之前将时间与GC状态隔离
  • 测试后最终强制GC估计清理对时序结果的影响