欢迎!请参阅关于页面以获取有关此功能的一些更多信息。
如果merge使用transients会更好。
补丁 - clj-1458-7.patch
方法 在transients和reduce之后,将c.c/merge迁移到核心中。保留旧版本作为merge1,用于新定义之前的情况。让APersistentMap/conj和ATransientMap/cons意识到IKVReduce。
附带的补丁保留了merge的两个现有行为- 元数据传播- 右侧的merge可以是Map.Entry、size=2的IPersistentVector和正常映射。
由以下人员审核
评论者:jawolfe
我今天将尝试这个补丁。
这个补丁(transient-merge.diff)让merge、merge-with和zipmap(因为它就在那里,显然也可从中受益transients)使用transients。
三个潜在问题- 因为它们依赖于transient和好友,我不得不移动函数。我认为这比正向声明更好。这是我能找到的最好的位置,但愿意将其移动到其他地方。- 我添加了多个arity,以避免将单参数transient化可能造成的性能成本。如果愿意,我可以撤销这项操作。- 因为transient maps不支持contains?(或find),我不得不稍微修改merge-with中的逻辑。
评论者:michalmarczyk
我在2012年5月30日为{{zipmap}}发布了一个单独的工单,附带补丁,CLJ-1005。
哎呀, 如果我越界了,那真的很抱歉。 如果这样可以简化事情,我很乐意从该补丁中删除这个更改——只是请告诉我。
评论者:gshayban
附加了一个备选方案,它将合并延迟到协议加载后,然后使用transducers。
评论者:michaelblume
看起来你的(get m k)被重复了两次——不应该在那个地方抛出吗?
呃,在我说的本地 put 中,'throw' 这个词用得不好。
是的,那就是——因为 CLJ-700 已经提交,所以之后将不再使用 get。
我们应该添加性能测试。合并两个地图,三个地图,多张地图,还要调整地图的大小,以及合并时调整碰撞的百分比。
我们需要回到(某些身份)逻辑,否则元数据会从除第一个提供的地图以外的其他地图中传播。我会稍后修复。
我不知道这是否应该是允许的,但这是打破
(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-with的使用,但没有看到测试其行为的测试。