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

正如在票据描述中提到的,之前附加的补丁遵循 into 的模式,其非瞬态启用定义在前端的 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))
评估计数: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,在 60 个样本中每次为 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
user=> (c/bench (zipmap ys ys))
评估计数:16639020,在 60 个样本中每次为 277317 调用。

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

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

显然,只要临时变量满足其契约,语义就被保留。

我想我可能没有为这个启动一个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。更新很简单 - 自动变基。以下是更新后的补丁。
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报告)
...