我知道我可以花时间评估一个功能,可以使用时间函数/宏在屏幕/标准输出上打印出来。
时间宏返回已计算函数的值,这使得内联使用它变得非常棒。但是我想在特定情况下自动测量运行时。
是否有一个函数可以返回某个库中的已用时间来帮助进行此基准测试?
答案 0 :(得分:31)
如果只是想要以编程方式捕获字符串,可以在使用 time 之前将* out *绑定到其他内容。
user=> (def x (with-out-str (time (+ 2 2))))
#'user/x
user=> x
"\"Elapsed time: 0.119 msecs\"\n"
如果您想要更多地控制格式,那么您可以使用Java的系统时间方法创建自己的 time 版本,这就是 time 宏在无论如何,引擎盖:
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 的调用。
答案 1 :(得分:27)
你可能想看看Hugo Duncan的Clojure基准测试库 - Criterium。
来自自述文件:
Criterium测量表达式的计算时间。它旨在解决基准测试的一些缺陷,特别是对JVM进行基准测试。
这包括:
- 多次评估的统计处理
- 包含预热期,旨在允许JIT编译器优化其代码
- 测试前清除gc,以便在测试前将时间与GC状态隔离
- 测试后的最终强制GC,以估计清理对时间结果的影响
答案 2 :(得分:0)
如果为您的函数生成Java绑定(并使用一些Clojure Maven插件重新配置),您甚至可以使用JMH(http://openjdk.java.net/projects/code-tools/jmh/),这可能是最好的JVM微基准测试工具。看看https://github.com/circlespainter/pulsar-auto-instrument-bench