MRo*_*lin 5 benchmarking clojure
小Clojure的功能有多快assoc?我怀疑它assoc在100ns到3us范围内工作,这使得它很难计时.
timeuser=> (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}
Run Code Online (Sandbox Code Playgroud)
显然有很多开销,所以我不相信这个基准.朋友们向我指出了Criterium,它处理了很多基准测试的痛苦(多次评估,预热JVM,GC请参见如何在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
Run Code Online (Sandbox Code Playgroud)
万一你错过了,这个操作平均需要-15ns.我知道Clojure非常神奇,但是负面的运行时似乎有点太好了.
真的,需要多长时间assoc?如何在Clojure中对微操作进行基准测试?
为什么不把它包裹在一个循环中并重新规范化呢?
\n\n在我的硬件上,
\n\n(bench (dotimes [_ 1000] (assoc d 3 3)))\nRun Code Online (Sandbox Code Playgroud)\n\n平均执行时间约为 1000 倍
\n\n(bench (assoc d 3 3))\nRun Code Online (Sandbox Code Playgroud)\n\n即,第一种情况约为 100 \xc2\xb5s,第二种情况约为 100 ns。如果您的单曲assoc在 Criteium 中“处于噪音中”,您可以尝试以相同的方式包装它并非常接近“内在”值。((dotimes [_ 1000] 1)时钟为 0.59 \xc2\xb5s,因此循环本身带来的额外开销相对较小。)