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

欢迎!请参阅关于页面以获取更多关于该功能的信息。

+1
Clojure
已关闭

'zipmap'构建一个不使用transient的映射,而transients可以提高性能。

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

性能

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

| 表达式 | 1.7.0-beta3 | +patch | |
| :-- | :-- | :-- | :-- | :-- |
| (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

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次抽样中为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毫秒(97.5%)

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

low-severe	 2 (3.3333 %)

异常值引起的方差:25.4675%。方差受异常值的影响适度。
nil

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

'user/ys

user=> (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微秒(25%)
执行时间上四分位数: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微秒(25%)
执行时间上四分位数:3.545549微秒(97.5%)
nil
`

只要transients满足它们的合约,语义显然得到保留。

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

0

评论由:jafingerhut

2012年8月15日创建的补丁0001-Use-transient-map-in-zipmap.2.patch无法在不考虑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
参考: https://clojure.atlassian.net/browse/CLJ-1005 (由 michalmarczyk 报告)
...