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

欢迎!请访问关于页面以了解更多关于如何使用本站的信息。

+1
Clojure

如果merge使用transients(临时数据结构)那就更好了。

补丁
- clj-1458-7.patch

方法
在core的核心部分之后迁移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及其相关内容,我不得不将它们移动。我认为这比前向声明更可取。这是我能找到的最佳位置,但如果需要,我可以将它们移动到其他地方。
- 为了避免对单个参数执行transient操作的潜在性能成本,我添加了多个arity。如果需要,我很乐意撤销此更改。
- 由于transient映射不支持contains?(或find),我不得不稍微修改merge-with中的逻辑。

0

由:michalmarczyk 添加评论

我在2012年5月30日为 {{zipmap}} 发布了一个单独的工单,并附带补丁:CLJ-1005。

0

评论由:jawolfe发布

啊,如果我的行为超出了范围,很抱歉。如果那样能简化问题,我很乐意从这次补丁中移除那个更改——只需要告诉我。

0

由:gshayban 添加评论

附上一种替代方法,在加载协议之后延迟合并,然后使用 transducers。

0

由:michaelblume 添加评论

看起来你调用(get m k)两次——这不应该是放在本地吗?

0

由:michaelblume 添加评论

嗯,我指的是在局部使用 put——‘抛出’这个用词是错误的。

0

由:gshayban 添加评论

是的,就像这样——在 CLJ-700 提交后不会使用 get。

我们还应该添加性能测试。合并两个、三个、多个映射,以及改变映射的大小,对于 merge-with,改变冲突的百分比。

需要回到(一些身份)逻辑,否则元数据是从除第一个提供以外的映射中传播的。我稍后修复。

0

由:michaelblume 添加评论

我不知道这是否是允许的,但这打破了

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

它在 compojure-api 中广泛使用。

0
0

由:michaelblume 添加评论

Ghadi, contains? 使用内部的 get,所以它仍然是两次获取,对吧?看起来使用 ::none 技巧可能更有效。

0

评论者:bronsa

这需要 if-let + find。

0

由:gshayban 添加评论

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

0

由:gshayban 添加评论

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

0

由:michaelblume 添加评论

不错 =)

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

...