如何在 Clojure 中对函数进行基准测试?
Posted
技术标签:
【中文标题】如何在 Clojure 中对函数进行基准测试?【英文标题】:How to benchmark functions in Clojure? 【发布时间】:2010-06-14 22:07:55 【问题描述】:我知道我可以获得评估函数所需的时间,可以使用时间函数/宏在屏幕/标准输出上打印出来。
时间宏返回评估函数的值,这使得内联使用它非常棒。但是我想在特定情况下自动测量运行时间。
是否有一个函数可以返回某个库中经过的时间来帮助进行基准测试?
【问题讨论】:
Profiling tool for Clojure?的可能重复 我不这么认为,提到的问题是关于外部基准测试,这个问题更多的是关于检测代码。我必须承认有人在寻找重复 5 年的问题时感到惊讶。 【参考方案1】:如果只是想以编程方式捕获字符串,您可以在使用 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 的调用替换为您喜欢的任何报告机制。
【讨论】:
谢谢,我也在研究这个。标准库确实符合要求。但除非您知道 Haskell 库,否则您不会在使用 google 时偶然发现它。 @PeterTillemans 好吧,现在我们是,因为 *** 中提到了它。 :-)【参考方案2】:您可能想查看 Hugo Duncan 的 Clojure 基准测试库 -- Criterium。
来自自述文件:
Criterium 衡量表达式的计算时间。它旨在解决基准测试的一些缺陷,尤其是针对 JVM 的基准测试。
这包括:
多个评估的统计处理 包含预热期,旨在让 JIT 编译器优化其代码 在测试前清除 gc,以在测试前将时间与 GC 状态隔离 测试后的最终强制 GC 以估计清理对计时结果的影响
【讨论】:
【参考方案3】:如果您为您的函数生成 Java 绑定(并通过一些 Clojure Maven 插件重新配置),您甚至可以使用 JMH (http://openjdk.java.net/projects/code-tools/jmh/),这可能是最好的 JVM 微基准测试工具。看看https://github.com/circlespainter/pulsar-auto-instrument-bench
【讨论】:
以上是关于如何在 Clojure 中对函数进行基准测试?的主要内容,如果未能解决你的问题,请参考以下文章