2024年Clojure调查问卷!中分享您的看法。

欢迎!请参阅关于页面了解更多有关此功能的信息。

+1
Clojure
已关闭

"zipmap"构建一个不带transients的映射,其中transients可以改进性能。

方法:内部使用transient映射,以及键和值的迭代器。像以前一样返回持久映射。定义也移动,使其位于#'transient下方。

性能

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

| 表达式 | 1.7.0-beta3 | +patch | |
| :-- | :-- | :-- | :-- | :-- |
| (zipmap xs xs) | 4.50 ms | 2.12 ms | 大型映射
| (zipmap ys ys) | 2.75 us | 2.07 us | 小型映射

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

审核:Alex Miller

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

13 个答案

0

评论者:aaron

为什么保留旧的实现并取消注释?如果我们打算迁移到新的实现,应该移除旧的实现。

0

评论者:michalmarczyk

正如在问题描述中提到的,先前附上的补丁遵循了into的非transient启用定义的模式,该定义在core.clj中以#_开头 -- 我不确定这是否适用于所有情况。

这是一个新补丁,其中移除了旧的实现。

0
by

评论者:jafingerhut

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

0
by

评论者:michalmarczyk

感谢你的提醒,Andy!我已经以新名称重新上传了新的补丁。

0
by

评论者:jafingerhut

擅自将审核状态从“不完整”改回“无”,以解决该工单标记为不完整的原因。

0
by

评论者:aaron

补丁看起来不错,且应用无误。我们应该运行其他测试来验证这是否提供了我们认为的改进。此外,是否有文档讨论了这个工单的起点?这里面的上下文不多。

0
by

评论者:michalmarczyk

Hi 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%)
nil
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 % 异常值使方差中度膨胀
nil

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

'用户/ys

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

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

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

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

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

显然,只要暂存满足其合同条件,语义就会被保留。

我想我可能没有为这个开始一个ggroup线程,抱歉。

0

评论者:jafingerhut

补丁 0001-Use-transient-map-in-zipmap.2.patch,日期为2012年8月15日,在2014年9月3日对Clojure进行一些提交之后,无法干净地应用到最新主分支上。

我没有检查这个补丁是否直接更新。有关如何更新补丁的建议,请参阅http://dev.clojure.org/display/community/Developing Patches中的“更新过时补丁”部分。

0
_由:michalmarczyk_发表的评论

谢谢,Andy。更新很直接——自动rebase。以下是更新后的补丁。
0

由:gshayban发表的评论

使用 clojure.lang.RT/iter 编写的补丁,在最佳情况下表现提升了大于30%。分配可能更少,但我没有测量。与CLJ-1499(更好的迭代器)相关

0

由:justinspedding发表的评论

4年后,这个核心命名空间中的zipmap实现仍未使用内部暂存映射。为什么从未应用这个更改?

0
_评论者:alexmiller_

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