【问题标题】:Microbenchmark Clojure functions微基准 Clojure 函数
【发布时间】:2014-04-04 15:43:42
【问题描述】:

问题

assoc 这样的小 Clojure 函数有多快?我怀疑assoc 在 100ns 到 3us 范围内运行,这使得计时很困难。

使用time

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 中对微操作进行基准测试?

【问题讨论】:

  • 只是好奇,您想提高应用程序的哪个部分的性能?
  • 我认为没有直接的答案。您可能想观看 Zach Tellmans 从今年的 Clojure 演讲中谈论“可预测的快速 Clojure”youtube.com/watch?v=iQwQXVM6oiY
  • @AlbusShin 目前我真的对assoc 的表现非常感兴趣。我对结构共享与复制和编辑下的哈希图性能感兴趣。

标签: clojure benchmarking


【解决方案1】:

为什么不把它包装在一个循环中并重新规范化?

在我的硬件上,

(bench (dotimes [_ 1000] (assoc d 3 3)))

平均执行时间大约是 1000 倍

(bench (assoc d 3 3))

即,第一种情况约为 100 µs,第二种情况约为 100 ns。如果您的 single-assoc 对 Criterium 来说是“噪音”,您可以尝试以相同的方式包装它并非常接近“内在”值。 ((dotimes [_ 1000] 1) 的时钟频率为 0.59 µs,因此循环本身带来的额外开销相对较小。)

【讨论】:

  • 这会利用缓存结果吗?还是每个assoc 调用都与第一个调用相同?
  • 从 Clojure 的角度来看,我认为你必须记住才能获得缓存。当然,硬件对其缓存的使用是另一回事,JVM 细节也是如此。但是上面的测试讲述了一个非常简单的故事。
【解决方案2】:

Criterium 尝试通过自己的测量来消除开销。这可能会导致快速函数的负面结果。请参阅自述文件的Measurement Overhead Estimation 部分。您的开销非常高。您可能会运行 (estimatated-overhead!) [sic] 几次以获取更准确的开销数字。

【讨论】:

    【解决方案3】:
    猜你喜欢
    • 2015-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-12
    • 2014-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多