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

欢迎!请查看关于页面了解更多关于如何使用本站的信息。

+1
Clojure
已关闭

'zipmap'构建地图时没有使用transient,而transient可以改善性能。

方法:在内部使用transient映射,并带有键值迭代器。像以前一样返回持久映射。定义也移动到#'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

如工单描述中提到的,之前附带的补丁采用了into的非transient启用定义的模式,其前的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%)
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 us ( 2.5%)
执行时间上四分位数:3.935160 us (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 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进行了一些提交后,无法干净地应用于最新主分支。

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

0
_由 michalmarczyk 发表的评论

谢谢,Andy。更新很简单——自动合并。这是更新的补丁。
0

由 gshayban 发表的评论

使用 clojure.lang.RT/iter 的新补丁,在最佳情况下性能提高了 >30%。可能分配较少,但我没有测量。CLJ-1499 (改进迭代器) 相关

0

由 justinspedding 发表的评论

4年后,这个核心名称空间中的zipmap实现仍然没有使用transient map。为什么它从未应用?

0
_由 alexmiller_ 发表的评论

在此提出了多种方法,尚未确定共识方法。需要一些专注时间来缩小范围,且尚未是优先事项。
0
by
参考: https://clojure.atlassian.net/browse/CLJ-1005(由 Michal Marczyk 报告)
...