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 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

如问题描述中所述,之前附加的补丁遵循以下模式:在core.clj中留下非持久启用定义前的#_,我不确定这是否在所有情况下都是期望的。

这里是一个移除了旧实现的新的补丁。

0投票
by

评论由:jafingerhut发表

感谢您更新补丁,Michal。很抱歉提出这么小的问题,但您介意使用不同的名字为更新的补丁吗?我知道JIRA可以处理具有相同名称的多个附加文件,但我的预筛选代码还不够聪明,这可能导致讨论时的困惑。

0投票
by

评论者:michalmarczyk

感谢您的提醒,Andy!我已经以新名称重新附加了新的补丁。

0投票
by

评论由:jafingerhut发表

假设在Michal更新补丁后,将审批状态从不完整改回无。这解决了该工单标记为不完整的原因。

0投票
by

评论者:aaron

这个补丁看起来不错,并且应用干净。我们是否应该运行额外的测试来验证这是否提供了我们认为的改进?另外,是否有一个讨论开始了这个工单?这里的上下文并不多。

0投票
by

评论者:michalmarczyk

嗨,Aaron,

感谢您调查此事!

根据我所观察到的,这个改动大大提高了大映射的{{zipmap}}时间。对于小映射,也有小幅的改进。以下是两个基本的Criterium基准(在REPL中定义为补丁中的{{transient-zipmap}})

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

'user/xs

user=> (last xs)
16383
user=> (c/bench (zipmap xs xs))
评估计数:60个样本中的2,320次调用,共计13,920次。

         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))
评估次数:21180次,共60个样本,353次调用。

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

执行时间下四分位数:2.618971 ms(2.5%)
执行时间上四分位数:3.025812 ms(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
user=> (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
user=> (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。更新很简单——自动rebase。这是更新后的补丁。
0投票

评论者:gshayban

使用clojure.lang.RT/iter的新补丁,在最佳情况下显示性能提高了30%以上。可能分配较少但未测量。CLJ-1499(更好的迭代器)相关

0投票

评论者:justinspedding

4年后,这个核心命名空间中的zipmap实现仍然没有使用内部临时映射。为什么从未应用这个补丁?

0投票
评论由:alexmiller_发表

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