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

欢迎!有关此工作方式的更多信息,请参阅关于页面。

+1投票
Clojure

如果merge使用transients,那会很好。

补丁
- clj-1458-7.patch

方法
在核心库中迁移c.c/merge,优先于transients和reduce。保留旧版本作为merge1,供在先于新定义的情况中使用。让APersistentMap/conj和ATransientMap/cons了解IKVReduce。

所附补丁保留merge的两个现有行为
- 元数据传播
- 合并的右边可以是Map.Entry,size=2的IPersistentVector和普通映射。

审核人

25 答案

0投票

评论者:jawolfe

我将今天尝试制作一个补丁。

0投票

评论者:jawolfe

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

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

0投票

评论人:michalmarczyk

我在12年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

Nothing, contains? 在幕后使用 get,所以仍然需要两次获取,对吗?似乎坚持使用 ::none 技巧会更高效。

0投票

评论者:bronsa

这里需要用到 if-let + find。

0投票

评论人:gshayban

新的补丁解决了迄今为止的所有问题

0投票

评论人:gshayban

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

0投票

评论人:michaelblume

不错 =)

这应该包含测试。如果我们想要保留与 MapEntry 合并的能力,我们应该测试它。这与其说是补丁的弱点,不如说是现有测试的弱点。我看到了在测试套件中多次使用 merge 和 merge-with,但我看不到一个测试目的就是测试它们的行为的测试。

...