欢迎!请参阅关于页面以了解更多关于如何工作的信息。
如果merge使用transients会更好。
补丁 - clj-1458-7.patch
方法 在核心库的合并操作中,在transients和reduce之后迁移c.c/。保留旧版本作为merge1,用于新定义之前的情况。让APersistentMap/conj和ATransientMap/cons了解IKVReduce。
附带的补丁保留了合并的两种现有行为- 元数据传播- 合并的右侧可以是Map.Entry、大小为2的IPersistentVector和普通映射。
由以下人员审核
评论者:jawolfe
我今天会尝试修改补丁。
这个补丁(transient-merge.diff)使得merge、merge-with和zipmap(由于它就在那里,并且显然也可以从transients中受益)使用transients。
三个潜在问题- 由于函数依赖于transient及其相关内容,我不得不将它们移动。我假设这比向前声明更好。这是我能找到的最佳位置,但愿意将它们移到别处。- 我添加了多个arity,以避免单参数transient可能带来的性能损失。如果需要,乐于撤销这个改动。- 我必须稍微修改merge-with中的逻辑,因为transient映射不支持contains?(或find)。
评论者:michalmarczyk
我在2012年5月30日为{{zipmap}}提交了一个单独的工单,带有补丁:CLJ-1005。
哎呀,如果你越界了,我很抱歉。如果这能让事情变得简单,我很乐意从这个补丁中删除这个更改 —— 只是要告诉我。
评论者:gshayban
附加了一种替代方案,即延迟合并直到协议加载完成后,然后再使用transducers。
评论者:michaelblume
看起来你正在做(获取m k)两次 —— 那个不应该是在局部抛出吗?
呃,我意思是,'throw'是一个不恰当的词。
是的,那是那个 —— 在CLJ-700被提交后,将不再使用get。
我们应该添加性能测试。合并两个映射、三个、许多映射,以及按映射大小变化,对于合并-with,则按冲突百分比变化。
需要回到(某些身份)逻辑,否则元数据会从除了提供的第一个映射之外的其他映射中传播。我会稍后修复。
我不知道这是否应该被允许,但这打破了
(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 几次被使用,但没有看到测试目的是测试它们的行为的测试。