2024 Clojure 状态调查! 中分享您的想法。

欢迎!请查阅 关于 页面以了解更多关于如何使用本网站的详细信息。

0
Clojure
*描述*
有时需要将一组值与单个值进行比较,Clojure 内部定义了一个用于此目的的谓词,该谓词与简单的部分应用 = 相比具有一些性能改进。

与Rich的先前讨论:https://groups.google.com/forum/#!topic/clojure-dev/0c-VNhEKVkI

*示例用法*

;;之前
(map (partial = 3) coll)
;;之后
(map (=to 3) coll)


*基准测试*

||测试||(部分 = 'foo)||#(= 'foo %)||=to 'foo||
|小型同质集合|217ns|165ns|39ns|
|小型异质集合,|192ns|167ns|41ns|
|大型同质集合|66us|52us|8us|
|大型异质集合|82us|66us|27us|

*完整基准测试输出*

(使用 'criterium.core)

(定义基准测试-f [f])
  (让 [colls [['foo 'foo 'foo]
             [1 :foo 'foo]
               (全部重复 1e3 'foo))
               (全部取 1e3 (周期 [1 :foo 'foo])))]]
    (循环 colls
      [(快速基准测试 (运行! f c)))])

(基准测试-f (部分 = 'foo))
警示:最终的GC需要 1.405293826432628 % 的运行时间
警示:最终的GC需要 10.202923149112559 % 的运行时间
评估计数:在 6 个样本的 519355 次调用中为 3116130。
执行时间平均值:217.723199 纳秒
执行时间标准偏差:29.425291 纳秒
执行时间下四分位数:189.944710 纳秒 (2.5%)
执行时间上四分位数:261.717351 纳秒 (97.5%)
超负荷使用:1.863362 纳秒
警示:最终的GC需要 4.2579397621583315 % 的运行时间
评估计数:在 6 个样本的 523106 次调用中为 3138636。
执行时间平均值:198.985418 纳秒
执行时间标准偏差:12.691848 纳秒
执行时间下四分位数:182.441245 纳秒 (2.5%)
执行时间上四分位数:207.839280 纳秒 (97.5%)
超负荷使用:1.863362 纳秒
警示:最终的GC需要 6.631646134523004 % 的运行时间
评估计数:在 6 个样本的 1673 次调用中为 10038。
执行时间平均值:66.977712 微秒
执行时间标准偏差:10.411821 微秒
执行时间下四分位数:59.620690 微秒 (2.5%)
执行时间上四分位数:84.483254 微秒 (97.5%)
超负荷使用:1.863362 纳秒

发现 1 个异常值在 6 个样本中 (16.6667 %)
低严重  1 (16.6667 %)
异常值变异:47.3059 % 异常值使方差略有膨胀
警示:最终的GC需要 5.272721959665122 % 的运行时间
评估计数:在 6 个样本的 1318 次调用中为 7908。
执行时间平均值:82.588512 微秒
执行时间标准偏差:5.215537 微秒
执行时间下四分位数:75.977936 微秒 (2.5%)
执行时间上四分位数:86.849982 微秒 (97.5%)
超负荷使用:1.863362 纳秒


(基准测试-f #(= 'foo %))
警示:最终的GC需要 1.284421364203217 % 的运行时间
警示:最终的GC需要 10.04376144830405 % 的运行时间
评估次数:3643032次,来自607172次调用中的6个样本。
             平均执行时间:165.393131纳秒
    执行时间标准差:1.041355纳秒
   执行时间下限分位数:164.277060纳秒(2.5%)
   执行时间上限分位数:166.849951纳秒(97.5%)
                   使用开销:1.605524纳秒
警告:最终GC占用了6.258680973295933%的运行时间
评估次数:3584574次,来自597429次调用中的6个样本。
             平均执行时间:167.659014纳秒
    执行时间标准差:3.821817纳秒
   执行时间下限分位数:164.175156纳秒(2.5%)
   执行时间上限分位数:173.210781纳秒(97.5%)
                   使用开销:1.605524纳秒

发现 1 个异常值在 6 个样本中 (16.6667 %)
    低严重等级     1(16.6667%)
 异常值方差:13.8889% 异常值使方差适度膨胀
警告:最终GC占用了6.914389197005716%的运行时间
评估次数:11196次,来自1866次调用中的6个样本。
             平均执行时间:52.593759微秒
    执行时间标准差:834.220092纳秒



(基准-f (=to 'foo))
警告:最终GC占用了7.40391654943877%的运行时间
评估次数:15169068次,来自2528178次调用中的6个样本。
平均执行时间:39.937424纳秒
执行时间标准差:2.782661纳秒
执行时间下限分位数:37.393937纳秒(2.5%)
执行时间上限分位数:42.780432纳秒(97.5%)
超负荷使用:1.863362 纳秒
警告:最终GC占用了5.986859953402835%的运行时间
评估次数:15199992次,来自2533332次调用中的6个样本。
平均执行时间:41.229082纳秒
执行时间标准差:2.815533纳秒
执行时间下限分位数:37.371527纳秒(2.5%)
执行时间上限分位数:43.208673纳秒(97.5%)
超负荷使用:1.863362 纳秒
警告:最终GC占用了5.039484046472016%的运行时间
评估次数:69462次,来自11577次调用中的6个样本。
平均执行时间:8.976972微秒
执行时间标准差:587.089991纳秒
执行时间下限分位数:8.505317微秒(2.5%)
执行时间上限分位数:9.744296微秒(97.5%)
超负荷使用:1.863362 纳秒
警告:最终GC占用了5.773010947849351%的运行时间
评估次数:23352次,来自3892次调用中的6个样本。
平均执行时间:27.277376微秒
执行时间标准差:2.115666微秒
执行时间下限分位数:25.719322微秒(2.5%)
执行时间上限分位数:30.123547微秒(97.5%)
超负荷使用:1.863362 纳秒


*(补丁)* 0001-CLJ-1843-add-to-for-faster-equality-check-against-kn.patch

7个答案

0
by

评论者:alexmiller

你看了(应用=3组)吗?只是好奇。

0
by

评论者:bronsa

相比 Util/equiv,Util/equivPred 的优势在于它可以假定提供的参数类型,避免了如 Util/equiv 需要做的多次实例检查,以确定内部使用的比较器,从而减少运行时成本。

0

评论者:alexmiller

你能否量化这些方法在 2-3 个集合大小之间的差异?

0
_评论者:bronsa_

以下是设置情况:


(使用 'criterium.core)

(defn =to [x]
  (let [pred (clojure.lang.Util/equivPred x)]
    (fn [y]
      (.equiv pred x y))))

(定义基准测试-f [f])
  (让 [colls [['foo 'foo 'foo]
             [1 :foo 'foo]
               (全部重复 1e3 'foo))
               (全部取 1e3 (周期 [1 :foo 'foo])))]]
    (循环 colls
      [(快速基准测试 (运行! f c)))])

(benchmark-f (partial = 'foo) 的结果是



警告:最终 GC 需要了 1.405293826432628 % 的运行时间
警示:最终的GC需要 10.202923149112559 % 的运行时间
评估计数:在 6 个样本的 519355 次调用中为 3116130。
执行时间平均值:217.723199 纳秒
执行时间标准偏差:29.425291 纳秒
执行时间下四分位数:189.944710 纳秒 (2.5%)
执行时间上四分位数:261.717351 纳秒 (97.5%)
超负荷使用:1.863362 纳秒
警示:最终的GC需要 4.2579397621583315 % 的运行时间
评估计数:在 6 个样本的 523106 次调用中为 3138636。
执行时间平均值:198.985418 纳秒
执行时间标准偏差:12.691848 纳秒
执行时间下四分位数:182.441245 纳秒 (2.5%)
执行时间上四分位数:207.839280 纳秒 (97.5%)
超负荷使用:1.863362 纳秒
警示:最终的GC需要 6.631646134523004 % 的运行时间
评估计数:在 6 个样本的 1673 次调用中为 10038。
执行时间平均值:66.977712 微秒
执行时间标准偏差:10.411821 微秒
执行时间下四分位数:59.620690 微秒 (2.5%)
执行时间上四分位数:84.483254 微秒 (97.5%)
超负荷使用:1.863362 纳秒

发现 1 个异常值在 6 个样本中 (16.6667 %)
低严重  1 (16.6667 %)
异常值变异:47.3059 % 异常值使方差略有膨胀
警示:最终的GC需要 5.272721959665122 % 的运行时间
评估计数:在 6 个样本的 1318 次调用中为 7908。
执行时间平均值:82.588512 微秒
执行时间标准偏差:5.215537 微秒
执行时间下四分位数:75.977936 微秒 (2.5%)
执行时间上四分位数:86.849982 微秒 (97.5%)
超负荷使用:1.863362 纳秒


(benchmark-f (=to 'foo)) 的结果是


警告:最终GC占用了7.40391654943877%的运行时间
评估次数:15169068次,来自2528178次调用中的6个样本。
平均执行时间:39.937424纳秒
执行时间标准差:2.782661纳秒
执行时间下限分位数:37.393937纳秒(2.5%)
执行时间上限分位数:42.780432纳秒(97.5%)
超负荷使用:1.863362 纳秒
警告:最终GC占用了5.986859953402835%的运行时间
评估次数:15199992次,来自2533332次调用中的6个样本。
平均执行时间:41.229082纳秒
执行时间标准差:2.815533纳秒
执行时间下限分位数:37.371527纳秒(2.5%)
执行时间上限分位数:43.208673纳秒(97.5%)
超负荷使用:1.863362 纳秒
警告:最终GC占用了5.039484046472016%的运行时间
评估次数:69462次,来自11577次调用中的6个样本。
平均执行时间:8.976972微秒
执行时间标准差:587.089991纳秒
执行时间下限分位数:8.505317微秒(2.5%)
执行时间上限分位数:9.744296微秒(97.5%)
超负荷使用:1.863362 纳秒
警告:最终GC占用了5.773010947849351%的运行时间
评估次数:23352次,来自3892次调用中的6个样本。
平均执行时间:27.277376微秒
执行时间标准差:2.115666微秒
执行时间下限分位数:25.719322微秒(2.5%)
执行时间上限分位数:30.123547微秒(97.5%)
超负荷使用:1.863362 纳秒
0
_评论者:bronsa_

使用 #(= 'foo %) 而不是 (partial = 'foo) 允许 = 的内联,从而使性能略好,但 =to 仍然明显优于其他方法

警示:最终的GC需要 1.284421364203217 % 的运行时间
警示:最终的GC需要 10.04376144830405 % 的运行时间
评估次数:3643032次,来自607172次调用中的6个样本。
             平均执行时间:165.393131纳秒
    执行时间标准差:1.041355纳秒
   执行时间下限分位数:164.277060纳秒(2.5%)
   执行时间上限分位数:166.849951纳秒(97.5%)
                   使用开销:1.605524纳秒
警告:最终GC占用了6.258680973295933%的运行时间
评估次数:3584574次,来自597429次调用中的6个样本。
             平均执行时间:167.659014纳秒
    执行时间标准差:3.821817纳秒
   执行时间下限分位数:164.175156纳秒(2.5%)
   执行时间上限分位数:173.210781纳秒(97.5%)
                   使用开销:1.605524纳秒

发现 1 个异常值在 6 个样本中 (16.6667 %)
    低严重等级     1(16.6667%)
 异常值方差:13.8889% 异常值使方差适度膨胀
警告:最终GC占用了6.914389197005716%的运行时间
评估次数:11196次,来自1866次调用中的6个样本。
             平均执行时间:52.593759微秒
    执行时间标准差:834.220092纳秒
   执行时间的较低四分位数:51.510161 µs (2.5%)
   执行时间的较高四分位数:53.367649 µs (97.5%)
                   使用开销:1.605524纳秒
警告:最终 GC 需要了 6.179040224498723 % 的运行时间
评估次数:6 样本的 1527 次调用中 9162 次。
             执行时间的平均值:66.527357 µs
    执行时间标准差:2.119652 µs
   执行时间的较低四分位数:65.308835 µs (2.5%)
   执行时间的较高四分位数:70.201570 µs (97.5%)
                   使用开销:1.605524纳秒


小型同构集合,*(partial = 'foo)*:217ns,*#(= 'foo %)*:165ns,*(=to 'foo)*:39ns
小型异构集合,*(partial = 'foo)*:192ns,*#(= 'foo %)*:167ns,*(=to 'foo)*:41ns
大型同构集合,*(partial = 'foo)*:66us,*#(= 'foo %)*:52us,*(=to 'foo)*:8us
大型异构集合,*(partial = 'foo)*:82us,*#(= 'foo %)*:66us,*(=to 'foo)*:27us
0

评论者:bronsa

显然,这是几年前就已经讨论过的问题,Rich 看起来对这一点持支持态度[链接]

0
参考: https://clojure.atlassian.net/browse/CLJ-1843 (由bronsa报告)
...