欢迎!请参阅关于页面了解有关此功能的一些更多信息。
如果merge使用transient会更好。
补丁 - clj-1458-7.patch
方法 迁移c.c/merge到核心库中,在transient和reduce之后。保留旧版本merge1,供使用新定义之前的情况使用。让APersistentMap/conj和ATransientMap/cons了解IKVReduce。
附加的补丁保留了merge的两个现有行为- 元数据传播- 合并的右侧可以是Map.Entry、大小为2的IPersistentVector和普通映射。
经审核
评论由:jawolfe
我将在今天尝试一个补丁。
此补丁(transient-merge.diff)使merge,merge-with和zipmap(因为它就在那里,显然也可以从transient中受益)使用transient。
三个潜在问题- 我必须移动这些函数,因为它们依赖于transient和相关功能。我假设这比正向声明更可取。这是我找到的最佳位置,但乐于将其移动到其他位置。- 我添加了多个可变参数数量,以避免由于transient单个参数而可能产生的性能成本。如果需要,我愿意撤销这一改动。- 我必须稍微改变merge-with中的逻辑,因为transient映射不支持contains?(或find)。
由 michalmarczyk 发表评论:
我在2012年5月30日为{{zipmap}}发布了一个单独的带有补丁的票据:CLJ-1005。
啊,如果我做得过分了,请见谅。如果这样能简化事情,我很乐意将这个更改从补丁中移除 - 请告诉我。
由 gshayban 发表评论:
附加一个替代方案:延迟合并到协议加载之后,然后使用transducers。
由 michaelblume 发表评论:
看起来你执行了两次(get m k) -- 那不应该是放一个局部变量中吗?
um,我在当地使用put,我的意思是,“throw”是一个糟糕的选择词。
是的,那就是 -- 在CLJ-700提交后,将不再使用get。
我们应该添加性能测试。合并两个、三个、多个地图,以及调整地图的大小,对于merge-with,则调整碰撞率。
需要回到(某些身份)逻辑,否则元数据会从除提供的第一张地图以外的地图中传播。我会稍后修复。
我不知道这是否应该被允许,但这个会失败。
(合并 {} (链接: :foo 'bar))
在野外的compojure-api中被使用
https://github.com/metosin/compojure-api/blob/0.16.6/src/compojure/api/meta.clj#L198
Ghadi,contains? 在暗地里使用 get,所以仍然是两次 get,对吧?看起来坚持使用 ::none 技巧会有更好的性能。
评论者:bronsa
这需要 if-let + find。
新的补丁解决迄今为止的关注点
CLJ-1458-transient-merge3.patch 移除愚蠢的内联宏,改用单例函数。
好的 =)
这应该附带测试。如果我们想保留与 MapEntry 合并的能力,我们应该进行测试。这与其说是补丁的弱点,不如说是现有测试的弱点。我看到在测试套件中几次使用了 merge 和 merge-with,但我没有看到据以测试它们行为的测试。