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

欢迎!有关此如何运作的更多信息,请参阅 关于 页面。

+1
Clojure

如果合并中使用 transient 会很棒。

补丁
- clj-1458-7.patch

方法
在核心中迁移 c.c/merge,在 transient 和 reduce 之后。保留旧版本作为 merge1 用于支持新定义之前的案例。让 APersistentMap/conj 和 ATransientMap/cons 充分了解 IKVReduce。

附加的补丁保留了合并的两个现有行为
- 元数据传播
- 合并的右侧可以是 Map.Entry、size=2 的 IPersistentVector 以及常规地图。

25 个答案

0

评论者:jawolfe

我今天会尝试打好补丁。

0

评论者:jawolfe

此补丁(transient-merge.diff)使 merge、merge-with 和 zipmap(因为它就在那里,显然也可以从 transient 中受益)使用 transient。

三个潜在问题
- 由于它们依赖于 transient 和相关函数,我不得不移动这些函数。我假设这比正向声明更可取。这是我能找到的最佳位置,但愿意将它们移动到其他地方。
- 我添加了多个 arity,以避免因 transient 化单个参数而产生的潜在性能成本。如果需要,可以撤销此操作。
- 我不得不稍微修改 merge-with 中的逻辑,因为 transient maps 不支持 contains?(或 find)。

0

评论由:michalmarczyk

我于2012年5月30日为{{zipmap}}提交了一项单独的工单,包括补丁,编号为CLJ-1005。

0

评论者:jawolfe

哦,对不起,如果那时我越界了。如果那样能让事情变得简单,我很乐意从这次补丁中移除那个更改——只需告诉我。

0

评论由:gshayban

附加了一个备选方案,即在协议加载后延迟合并,然后使用transducers。

0

评论由:michaelblume

看起来你重复做了(get m k)——这不应该在局部范围内执行吗?

0

评论由:michaelblume

我的意思是在局部范围的put操作中,'throw'是一个不当的词语。

0

评论由:gshayban

是的,那就是——在CLJ-700被提交之后不再使用get。

我们应该添加性能测试。合并两个、三个、多个映射,还要注意映射的大小,对于合并在出现冲突时也要变化百分比。

需要回归到(some identity)逻辑,否则除了第一个提供的映射之外的映射会将元数据传播出去。我会稍后修复。

0

评论由:michaelblume

我不知道这是不是
应该允许的,但这会中断

(merge {} (link: :foo 'bar))

该功能被compojure-api广泛应用于野外

0
0

评论由:michaelblume

Ghadi,contains?在幕后使用get,所以它仍然是两次get,对吧?看起来使用::none技巧可能会有更高的性能。

0

评论者:bronsa

这需要if-let + find。

0

评论由:gshayban

新的补丁解决了迄今为止的担忧

0

评论由:gshayban

CLJ-1458-transient-merge3.patch移除了愚蠢的内联宏,使用单例函数

0

评论由:michaelblume

很棒 =)

应该附上测试结果。如果我们希望保留与MapEntry合并的能力,我们应该进行测试。这与其说是补丁的弱点,不如说现有测试的弱点。我在测试套件中看到 merge 和 merge-with 几次被使用,但没有看到检查它们行为的测试。

...