如何在 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 中对函数进行基准测试?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spark 控制台中对性能进行基准测试?

如何在处理程序中对龙卷风处理程序进行基准测试?

在 C# 中对小代码示例进行基准测试,这个实现可以改进吗?

在 JMH 中对具有不同值的循环进行微基准测试

在Go中对gRPC+ProtoBuf与Http+Json进行基准测试

对单个函数进行基准测试