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

欢迎!请参阅关于页面以了解更多关于这个网站如何运作的信息。

0
Clojure
*描述*
比较一个值集合与单个值有时很有用,clojure 内部定义了一个用于此目的的谓词,它在部分应用 = 上具有一些性能改进。

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

*示例用法*

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


*基准测试*

||test||(partial = 'foo)||#(= 'foo %)||(=to 'foo)||
|小型均匀集合|217ns|165ns|39ns|
|小型异构集合,|192ns|167ns|41ns|
|大型的均匀集合|66us|52us|8us|
|大型的异构集合|82us|66us|27us|

*完整的基准测试输出*

(use 'criterium.core)

(defn benchmark-f [f]
  (let [colls [['foo 'foo 'foo]
               [1 :foo 'foo]
               (doall (repeat 1e3 'foo))
               (doall (take 1e3 (cycle [1 :foo 'foo])))]]
    (doseq [c colls]
      (quick-bench (run! f c)))))

(benchmark-f (partial = 'foo))
警告:GC 最终所需占 1.405293826432628 % 的运行时间
警告:GC 最终所需占 10.202923149112559 % 的运行时间
评估计数:3116130 在 6 个样本的 519355 次调用中。
执行时间均值:217.723199 纳秒
执行时间标准差:29.425291 纳秒
执行时间下四分位数:189.944710 纳秒 (2.5%)
执行时间上四分位数:261.717351 纳秒 (97.5%)
开销使用:1.863362 纳秒
警告:GC 最终所需占 4.2579397621583315 % 的运行时间
评估计数:3138636 在 6 个样本的 523106 次调用中。
执行时间均值:198.985418 纳秒
执行时间标准差:12.691848 纳秒
执行时间下四分位数:182.441245 纳秒 (2.5%)
执行时间上四分位数:207.839280 纳秒 (97.5%)
开销使用:1.863362 纳秒
警告:GC 最终所需占 6.631646134523004 % 的运行时间
评估计数:10038 在 6 个样本的 1673 次调用中。
执行时间均值:82.588512 微秒
执行时间标准差:10.411821 微秒
执行时间下四分位数:59.620690 微秒 (2.5%)
执行时间上四分位数:84.483254 微秒 (97.5%)
开销使用:1.863362 纳秒

在 6 个样本中发现了 1 个异常值 (16.6667 %)
低严重  1 (16.6667 %)
从异常值中测出的方差:47.3059 % 异常值导致方差中度膨胀
警告:GC 最终所需占 5.272721959665122 % 的运行时间
评估计数:7908 在 6 个样本的 1318 次调用中。
执行时间均值:82.588512 微秒
执行时间标准差:5.215537 µs
执行时间下四分位数:75.977936 µs(2.5%)
执行时间上四分位数:86.849982 µs(97.5%)
开销使用:1.863362 纳秒


(基准-f #(= 'foo %))
警告:最终垃圾回收占运行时1.284421364203217 %
警告:最终垃圾回收占运行时10.04376144830405 %
评估次数:在6个样本中,共3643032次,每个样本调用607172次。
             执行时间平均值:165.393131 ns
    执行时间标准差:1.041355 ns
   执行时间下四分位数:164.277060 ns(2.5%)
   执行时间上四分位数:166.849951 ns(97.5%)
                   开销:1.605524 ns
警告:最终垃圾回收占运行时6.258680973295933 %
在6个样本中,共3584574次评估,每个样本调用597429次。
             执行时间平均值:167.659014 ns
    执行时间标准差:3.821817 ns
   执行时间下四分位数:164.175156 ns(2.5%)
   执行时间上四分位数:173.210781 ns(97.5%)
                   开销:1.605524 ns

在 6 个样本中发现了 1 个异常值 (16.6667 %)
    低严重      1 (16.6667 %)
异常值方差:13.8889 % 方差受到异常值的影响适中
警告:最终垃圾回收占运行时6.914389197005716 %
在6个样本中,共11196次评估,每个样本调用1866次。
             执行时间平均值:52.593759 µs
    执行时间标准差:834.220092 ns



(基准-f (=to 'foo))
警告:最终垃圾回收占运行时7.40391654943877 %
在6个样本中,共15169068次评估,每个样本调用2528178次。
执行时间平均值:39.937424 ns
执行时间标准差:2.782661 ns
执行时间下四分位数:37.393937 ns(2.5%)
执行时间上四分位数:42.780432 ns(97.5%)
开销使用:1.863362 纳秒
警告:最终垃圾回收占运行时5.986859953402835 %
在6个样本中,共15199992次评估,每个样本调用2533332次。
执行时间平均值:41.229082 ns
执行时间标准差:2.815533 ns
执行时间下四分位数:37.371527 ns(2.5%)
执行时间上四分位数:43.208673 ns(97.5%)
开销使用:1.863362 纳秒
警告:最终垃圾回收占运行时5.039484046472016 %
在6个样本中,共69462次评估,每个样本调用11577次。
执行时间平均值:8.976972 µs
执行时间标准差:587.089991 ns
执行时间下四分位数:8.505317 µs(2.5%)
执行时间上四分位数:9.744296 µs(97.5%)
开销使用:1.863362 纳秒
警告:最终垃圾回收占运行时5.773010947849351 %
在6个样本中,共23352次评估,每个样本调用3892次。
执行时间平均值:27.277376 µs
执行时间标准差:2.115666 µs
执行时间下四分位数:25.719322 µs(2.5%)
执行时间上四分位数:30.123547 µs(97.5%)
开销使用:1.863362 纳秒


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

7 个回答

0

评论人:alexmiller

你查看过(应用 = 3 coll)了吗?仅是出于好奇。

0
by

评论人:bronsa

Util/equivPred 优于 Util/equiv 的优势在于,它可以假定提供的参数类型,避免了 Util/equiv 为了确定内部使用的比较器而必须进行的多次实例检查的运行时成本。

0
by

评论人:alexmiller

你能量化这两种方法在 2-3 个集合大小上的区别吗?

0
by
_评论人:bronsa_

以下是设置


(use 'criterium.core)

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

(defn benchmark-f [f]
  (let [colls [['foo 'foo 'foo]
               [1 :foo 'foo]
               (doall (repeat 1e3 'foo))
               (doall (take 1e3 (cycle [1 :foo 'foo])))]]
    (doseq [c colls]
      (quick-bench (run! f c)))))

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



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

在 6 个样本中发现了 1 个异常值 (16.6667 %)
低严重  1 (16.6667 %)
从异常值中测出的方差:47.3059 % 异常值导致方差中度膨胀
警告:GC 最终所需占 5.272721959665122 % 的运行时间
评估计数:7908 在 6 个样本的 1318 次调用中。
执行时间均值:82.588512 微秒
执行时间标准差:5.215537 µs
执行时间下四分位数:75.977936 µs(2.5%)
执行时间上四分位数:86.849982 µs(97.5%)
开销使用:1.863362 纳秒


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


警告:最终垃圾回收占运行时7.40391654943877 %
在6个样本中,共15169068次评估,每个样本调用2528178次。
执行时间平均值:39.937424 ns
执行时间标准差:2.782661 ns
执行时间下四分位数:37.393937 ns(2.5%)
执行时间上四分位数:42.780432 ns(97.5%)
开销使用:1.863362 纳秒
警告:最终垃圾回收占运行时5.986859953402835 %
在6个样本中,共15199992次评估,每个样本调用2533332次。
执行时间平均值:41.229082 ns
执行时间标准差:2.815533 ns
执行时间下四分位数:37.371527 ns(2.5%)
执行时间上四分位数:43.208673 ns(97.5%)
开销使用:1.863362 纳秒
警告:最终垃圾回收占运行时5.039484046472016 %
在6个样本中,共69462次评估,每个样本调用11577次。
执行时间平均值:8.976972 µs
执行时间标准差:587.089991 ns
执行时间下四分位数:8.505317 µs(2.5%)
执行时间上四分位数:9.744296 µs(97.5%)
开销使用:1.863362 纳秒
警告:最终垃圾回收占运行时5.773010947849351 %
在6个样本中,共23352次评估,每个样本调用3892次。
执行时间平均值:27.277376 µs
执行时间标准差:2.115666 µs
执行时间下四分位数:25.719322 µs(2.5%)
执行时间上四分位数:30.123547 µs(97.5%)
开销使用:1.863362 纳秒
0
by
_评论人:bronsa_

使用 #(= 'foo %) 而不是 (partial = 'foo) 可以内有化 = 并略微提高性能,但 =to 仍有明显优势

警告:最终垃圾回收占运行时1.284421364203217 %
警告:最终垃圾回收占运行时10.04376144830405 %
评估次数:在6个样本中,共3643032次,每个样本调用607172次。
             执行时间平均值:165.393131 ns
    执行时间标准差:1.041355 ns
   执行时间下四分位数:164.277060 ns(2.5%)
   执行时间上四分位数:166.849951 ns(97.5%)
                   开销:1.605524 ns
警告:最终垃圾回收占运行时6.258680973295933 %
在6个样本中,共3584574次评估,每个样本调用597429次。
             执行时间平均值:167.659014 ns
    执行时间标准差:3.821817 ns
   执行时间下四分位数:164.175156 ns(2.5%)
   执行时间上四分位数:173.210781 ns(97.5%)
                   开销:1.605524 ns

在 6 个样本中发现了 1 个异常值 (16.6667 %)
    低严重      1 (16.6667 %)
异常值方差:13.8889 % 方差受到异常值的影响适中
警告:最终垃圾回收占运行时6.914389197005716 %
在6个样本中,共11196次评估,每个样本调用1866次。
             执行时间平均值:52.593759 µs
    执行时间标准差:834.220092 ns
   执行时间下四分位数:51.510161 微秒(2.5%)
   执行时间上四分位数:53.367649 微秒(97.5%)
                   开销:1.605524 ns
警告:最终 GC 需要了 6.179040224498723 % 的运行时
评估计数:6 样本中的 9162 次
             执行时间平均值:66.527357 微秒
    执行时间标准偏差:2.119652 微秒
   执行时间下四分位数:65.308835 微秒(2.5%)
   执行时间上四分位数:70.201570 微秒(97.5%)
                   开销:1.605524 ns


小型同质集合,*(partial = 'foo)*: 217 纳秒,*#(= 'foo %): 165 纳秒,*(=to 'foo)*: 39 纳秒
小型异质集合,*(partial = 'foo)*: 192 纳秒,*#(= 'foo %): 167 纳秒,*(=to 'foo)*: 41 纳秒
大型同质集合,*(partial = 'foo)*: 66 微秒,*#(= 'foo %): 52 微秒,*(=to 'foo)*: 8 微秒
大型异质集合,*(partial = 'foo)*: 82 微秒,*#(= 'foo %): 66 微秒,*(=to 'foo)*: 27 微秒
0
by

评论人:bronsa

显然,这已经是几年前讨论过的事情了,Rich对此表示同意 https://groups.google.com/forum/#!topic/clojure-dev/0c-VNhEKVkI

0
...