请分享您的想法,参加2024年 Clojure 状态调查!

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

+1
Clojure
已关闭

“zipmap 构建了一个不使用短暂映射的映射,而短暂映射可能会提升性能。”

方法:在内部使用短暂映射,同时使用键和值的迭代器,返回一个持久映射。定义也被移动到 `'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

如问题描述中所述,之前附加的补丁遵循了以下模式:将非瞬态启用的定义留在core.clj中,并在其前面添加了#_。我不是很清楚这是否在所有情况下都是可取的。

这里有一个移除了老实现的新的补丁。

0

评论者:jafingerhut

谢谢您更新补丁,Michal。很抱歉提出这样一个小问题,但您能不能为更新的补丁使用不同的名字?我知道JIRA可以处理具有相同名称的多个附件,但我的预筛查代码还没有那么智能化,这可能会导致讨论时的混淆。

0

评论者:michalmarczyk

感谢您通知我,Andy!我已经用一个新的名称重新附加了新的补丁。

0

评论者:jafingerhut

在天真地将审批状态从“ incomplete”改回“ none”后,Michal更新了补丁,解决了问题标记为“ incomplete”的原因。

0

评论者:aaron

补丁看起来不错,并且可以干净地应用。我们应该运行哪些额外的测试来验证这个补丁是否提供了我们期望的改进。此外,是否有关于启动这个 ticket 的讨论?这里的上下文不多。

0

评论者:michalmarczyk

Hi Aaron,

感谢您调查此事!

根据我观察到的,这个改动极大地提高了{{zipmap}}在大型映射中的效率。对于小型映射,也有一定的提升。以下是两个基础的基准测试({{transient-zipmap}}定义在补丁中的REPL里)

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

'user/xs

user=> (last xs)
16383
user=> (c/bench (zipmap xs xs))
评估次数:13920次,在60个包含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))
评估次数:21180次,在353个调用中的60个样本。

         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
user=> (c/bench (zipmap ys ys))
评估次数:16639020次,在60个样本的277317个调用中。

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

执行时间下四分位数:3.638146微秒(2.5%)
执行时间上四分位数:3.935160微秒(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微秒(2.5%)
执行时间上四分位数:3.545549微秒(97.5%)
nil
`

只要临时值履行它们的契约,语义就可以保留。

我想我可能没有启动ggroup线程,抱歉。

0

评论者:jafingerhut

2012年8月15日创建的补丁0001-Use-transient-map-in-zipmap.2.patch在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实现仍然没有使用内部临时map。为什么从来没有应用这个?

0
评论者:alexmiller

在此提出了多种方法,尚未确定共识方法。需要集中一段时间来缩小范围,目前还不是优先事项。
0
参考: https://clojure.atlassian.net/browse/CLJ-1005(由michalmarczyk报告)
...