问题
小型Clojure的功能有多快,如 assoc
?我怀疑 assoc
在100ns到3us的范围内运行,这使得它很难计时 .
使用时间
user=> (def d {1 1, 2 2})
#'user/d
user=> (time (assoc d 3 3))
"Elapsed time: 0.04989 msecs"
{1 1, 2 2, 3 3}
显然有很多开销,所以我不相信这个基准 . 朋友们指出我Criterium处理了很多基准测试的痛苦(多次评估,使JVM升温,GC见How to benchmark functions in Clojure?) .
使用Criterium
可悲的是,在如此小的基准上,即使是Criterium也似乎失败了
user=> (use 'criterium.core)
nil
user=> (def d {1 1 2 2})
#'user/d
user=> (bench (assoc d 3 3))
WARNING: JVM argument TieredStopAtLevel=1 is active, and may lead to unexpected results as JIT C2 compiler may not be active. See http://www.slideshare.net/CharlesNutter/javaone-2012-jvm-jit-for-dummies.
WARNING: Final GC required 1.694448681330372 % of runtime
Evaluation count : 218293620 in 60 samples of 3638227 calls.
Execution time mean : -15.677491 ns
Execution time std-deviation : 6.093770 ns
Execution time lower quantile : -20.504699 ns ( 2.5%)
Execution time upper quantile : 1.430632 ns (97.5%)
Overhead used : 123.496848 ns
万一你错过了,这个操作平均需要-15ns . 我知道Clojure非常神奇,但是负面的运行时似乎有点太好了 .
重复问题
真的, assoc
需要多长时间?如何在Clojure中对微操作进行基准测试?
3 回答
为什么不将它包装在循环中并重新规范化?
在我的硬件上,
产生的平均执行时间约为1000倍
即,第一种情况下约为100μs,第二种情况下为100ns . 如果您的单个
assoc
是Criterium的"in the noise",您可以尝试以相同的方式包装它并且非常接近"intrinsic"值 . ((dotimes [_ 1000] 1)
时钟为.59μs,因此环路本身施加的额外开销相对较小 . )Criterium试图通过自己的测量来消除开销 . 这可能导致快速功能的负面结果 . 请参阅自述文件的Measurement Overhead Estimation部分 . 你的开销很可疑 . 您可以运行几次
(estimatated-overhead!)
[原文如此]进行采样,以获得更准确的开销数字 .Andy Fingerhut已经维持了一段时间 .
首页 - http://jafingerhut.github.io/clojure-benchmarks-results/Clojure-benchmarks.html
结果 - http://jafingerhut.github.io/clojure-benchmarks-results/Clojure-expression-benchmark-graphs.html
ClojureScript:
项目 - https://github.com/netguy204/cljs-bench
结果 - http://www.50ply.com/cljs-bench/