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

欢迎!请参阅关于页面以获取有关其工作原理的更多信息。

+1
Clojure
已关闭

'zipmap 在没有使用 transients 的情况下构建映射,而 transients 可以提高性能。

方法: 在内部使用一个暂态映射,再加上键和值的迭代器。返回的映射与之前相同。定义也被移动,让它位于 `'transient` 之下。

性能

(def xs (range 16384))
(def ys (range 16))

| 表达式 | 1.7.0-beta3 | +补丁 | |
| :-- | :-- | :-- | :-- | :-- |
| (zipmap xs xs) | 4.50 毫秒 | 2.12 毫秒 | 大映射
| (zipmap ys ys) | 2.75 微秒 | 2.07 微秒 | 小映射

补丁: CLJ-1005-zipmap-iterators.patch

审核者: Alex Miller

关闭时标记为: 已在 1.10.2-rc1 中修复

13 答案

0

评论者:aaron

为什么旧的实现保留并注释掉?如果我们打算转向新的实现,那么应该删除旧的一个。

0

评论者:michalmarczyk

如工单描述中所述,之前在core.clj中附加的补丁遵循以下模式:在非瞬态启用定义中留下带有前面#_的字符 -- 我不确定这是否在所有情况下都是期望的行为。

这里有一个新补丁,其中删除了旧的实现。

0

评论者:jafingerhut

感谢您更新了补丁,Michal。很抱歉提出这样一个小问题,但您是否可以更改更新补丁的名称?我知道JIRA可以处理同名多个附加文件,但我的预筛代码还不够聪明,这可能会导致讨论补丁时产生混淆。

0

评论者:michalmarczyk

很感谢您的提醒,Andy!我已经用新的名字重新粘贴了新的补丁。

0

评论者:jafingerhut

未经许可,将Michal的补丁添加后,将审批从“Incomplete”更改为“None”,解决了这个工单被标记为“Incomplete”的原因。

0

评论者:aaron

补丁看起来不错,并且应用没有任何问题。我们还应该运行其他测试来验证这是否提供了我们期望的改进。此外,是否有关于开始此工票的讨论?这里没有太多上下文。

0

评论者:michalmarczyk

嗨Aaron,

感谢您调查此事!

据我所观察,此更改极大地改善了{{zipmap}}对于大映射的时间。对于小映射,也有一些改进。以下是有两个基本的Criterium基准({{transient-zipmap}}在REPL中定义,如补丁中所述)

`
;;大型映射
user=>(def xs(range 16384))

'user/xs

user=>(last xs)
16383
user=>(c/bench(zipmap xs xs))
评估次数:在60次样本中为13920(每次232次调用)。

         Execution time mean : 4.329635 ms
Execution time std-deviation : 77.791989 us

执行时间下四分位数:4.215050毫秒(2.5%)
执行时间上四分位数:4.494120毫秒(97.5%)
nil
user=>(c/bench(transient-zipmap xs xs))
评估次数:在60次样本中为21180(每次353次调用)。

         Execution time mean : 2.818339 ms
Execution time std-deviation : 110.751493 us

执行时间下四分位数:2.618971毫秒(2.5%)
执行时间上四分位数:3.025812 ms(97.5%)

在60个样本中发现了2个异常值(3.3333%)

low-severe	 2 (3.3333 %)

异常值方差:25.4675% 异常值使得方差适度膨胀
nil

;;; 小图
用户=> (def ys (range 16))

'用户/ys

用户=> (last ys)
15
用户=> (c/bench (zipmap ys ys))
评估次数:16639020次,分布在60个样本中的277317次调用。

         Execution time mean : 3.803683 us
Execution time std-deviation : 88.431220 ns

执行时间下四分位数:3.638146 us(2.5%)
执行时间上四分位数:3.935160 us(97.5%)
nil
用户=> (c/bench (transient-zipmap ys ys))
评估次数:18536880次,分布在60个样本中的308948次调用。

         Execution time mean : 3.412992 us
Execution time std-deviation : 81.338284 ns

执行时间下四分位数:3.303888 us(2.5%)
执行时间上四分位数:3.545549 us(97.5%)
nil
`

只要瞬时值满足其合同语义,语义就可以保持不变。

我想我可能没有为这个项目启动ggroup线程,抱歉。

0

评论者:jafingerhut

补丁0001-Use-transient-map-in-zipmap.2.patch(日期:2012年8月15日)在2014年9月3日对Clojure进行了一些提交之后,无法清洁地应用到最新的master分支。

我没有检查此补丁是否容易更新。请参阅“更新过时的补丁”部分,了解有关如何更新补丁的建议:http://dev.clojure.org/display/community/Developing Patches

0
_由 michalmarczyk 发表的评论

谢谢,Andy。更新很简单——自动变基。以下是更新后的补丁。
0

由 gshayban 发表的评论

使用 clojure.lang.RT/iter 的新补丁。在最佳情况下,性能比之前的代码提高了超过30%。内存分配可能较少,但我没有进行测量。与 CLJ-1499(更好的迭代器)相关。

0

由 justinspedding 发表的评论

4年后,core命名空间中的zipmap实现仍然没有使用瞬时映射表。为什么从未应用过这个?

0
_由 alexmiller 发表的评论

这里提出了多种方法,尚未确定共识方法。需要一些时间来缩小范围,目前尚不是优先事项。
0
参考:https://clojure.atlassian.net/browse/CLJ-1005(由 michalmarczyk 报告)
...