2024 Clojure状态调查!中分享你的看法。

欢迎!请查看关于页面以了解更多关于如何工作的信息。

+1 投票
Clojure
已关闭

zipmap构建一个没有transient的map,而在transient可以改进性能的情况下。

方法:内部使用transient map,以及键和值的迭代器。返回的持久map与之前相同。定义也被移动,以便它位于'#transient'之下。

性能

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

| 表达式 | 1.7.0-beta3 | +补丁 |
| :-- | :-- | :-- | :-- | :-- |
| (zipmap xs xs) | 4.50 ms | 2.12 ms | 大型map
| (zipmap ys ys) | 2.75 us | 2.07 us | 小型map

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

审核者:Alex Miller

已关闭,备注:在1.10.2-rc1中修复

13 个回答

0 投票

评论由:aaron发布

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

0 投票

评论由:michalmarczyk发布

如票据描述中所述,之前附上的补丁遵循非transient-启用定义的into模式,保留在core.clj中,前面带有#_,我不确定这是否在所有情况下都是可取的。

这里有一个新的补丁,已经移除了旧的实现。

0 投票

评论由:jafingerhut 发布

感谢您更新补丁,Michal。很抱歉提出如此小的问题,但您能否为更新的补丁使用一个不同的名字?我知道JIRA可以处理具有相同名称的多个附件,但是我的预筛选代码还不够聪明,这可能导致在讨论补丁时产生混淆。

0 投票

评论由:michalmarczyk发布

多谢提醒,Andy!我已经以新名字重新附上了新的补丁。

0 投票

评论由:jafingerhut 发布

假设在Michal的更新补丁添加后,将批准状态从'不完整'改为'无',解决导致工单被标记为不完整的原因。

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个样本中的232次调用,共13920次。

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

执行时间最低分位数:4.215050毫秒(2.5%)
执行时间最高分位数:4.494120毫秒(97.5%)
None
user=> (c/bench (transient-zipmap xs xs))
评估次数:60个样本中的353次调用,共21180次。

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

执行时间最低分位数:2.618971毫秒(2.5%)
执行时间最高分位数:3.025812毫秒(97.5%)

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

low-severe	 2 (3.3333 %)

异常值引起的方差:25.4675%,方差被异常值适度地膨胀
None

;;; 小型映射
用户=> (def ys (range 16))

'用户/ys

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

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

执行时间下四分位数:3.638146微秒 (2.5%)
执行时间上四分位数:3.935160微秒 (97.5%)
None
用户=> (c/bench (transient-zipmap ys ys))
评估计数:在60个样本中,共有308948次调用,总计18536880次。

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

执行时间下四分位数:3.303888微秒 (2.5%)
执行时间上四分位数:3.545549微秒 (97.5%)
None
`

显然,只要瞬态能够满足其合约,语义得到保留。

我认为我可能没有为此开启一个ggroup线程,抱歉。

0 投票

评论由:jafingerhut 发布

补丁0001-使用瞬态映射在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年后,这个核心命名空间中的zipmap实现仍未使用瞬态映射。为什么从未应用这个更新?

0 投票
_评论者为:alexmiller_

这里提出了多种方法,但尚未确定具有共识的方法。需要一些关注时间来缩小范围,并且尚未成为优先任务。
0 投票
参考信息:https://clojure.atlassian.net/browse/CLJ-1005(由michalmarczyk报告)
...