欢迎!有关此如何运作的更多信息,请参阅 关于 页面。
如果合并中使用 transient 会很棒。
补丁 - clj-1458-7.patch
方法 在核心中迁移 c.c/merge,在 transient 和 reduce 之后。保留旧版本作为 merge1 用于支持新定义之前的案例。让 APersistentMap/conj 和 ATransientMap/cons 充分了解 IKVReduce。
附加的补丁保留了合并的两个现有行为- 元数据传播- 合并的右侧可以是 Map.Entry、size=2 的 IPersistentVector 以及常规地图。
由
评论者:jawolfe
我今天会尝试打好补丁。
此补丁(transient-merge.diff)使 merge、merge-with 和 zipmap(因为它就在那里,显然也可以从 transient 中受益)使用 transient。
三个潜在问题- 由于它们依赖于 transient 和相关函数,我不得不移动这些函数。我假设这比正向声明更可取。这是我能找到的最佳位置,但愿意将它们移动到其他地方。- 我添加了多个 arity,以避免因 transient 化单个参数而产生的潜在性能成本。如果需要,可以撤销此操作。- 我不得不稍微修改 merge-with 中的逻辑,因为 transient maps 不支持 contains?(或 find)。
评论由:michalmarczyk
我于2012年5月30日为{{zipmap}}提交了一项单独的工单,包括补丁,编号为CLJ-1005。
哦,对不起,如果那时我越界了。如果那样能让事情变得简单,我很乐意从这次补丁中移除那个更改——只需告诉我。
评论由:gshayban
附加了一个备选方案,即在协议加载后延迟合并,然后使用transducers。
评论由:michaelblume
看起来你重复做了(get m k)——这不应该在局部范围内执行吗?
我的意思是在局部范围的put操作中,'throw'是一个不当的词语。
是的,那就是——在CLJ-700被提交之后不再使用get。
我们应该添加性能测试。合并两个、三个、多个映射,还要注意映射的大小,对于合并在出现冲突时也要变化百分比。
需要回归到(some identity)逻辑,否则除了第一个提供的映射之外的映射会将元数据传播出去。我会稍后修复。
我不知道这是不是应该允许的,但这会中断
(merge {} (link: :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 几次被使用,但没有看到检查它们行为的测试。