欢迎!请参阅关于页面以获取更多关于此如何工作的信息。
如果merge使用transients会更好。
补丁 - clj-1458-7.patch
方法 将c.c/merge迁移到核心代码库中,在transients和reduce之后。保留旧版本merge1以便在涉及较新定义之前的情况中使用。使APersistentMap/conj和ATransitionMap/cons意识到IKVReduce。
附带的补丁保留了merge的两种现有行为- 元数据传播- 合并的右侧可以是Map.Entry,一个size=2的IPersistentVector以及常规映射。
经请求筛选
评论由:jawolfe发表
我今天将尝试一下补丁。
这个补丁(transient-merge.diff)使得merge、merge-with,以及zipmap(因为它紧挨着,并且显然也可以从transients中受益)使用transients。
三个潜在问题- 由于这些函数依赖于transient和相关函数,我不得不移动它们。我假设这比正向声明更好。这是我找到的最佳位置,但我愿意将它们移动到其他地方。- 为了避免将单个参数transient化可能带来的性能成本,我添加了多个参数。如果需要,我愿意撤销这一举措。- 由于transient映射不支持contains?(或find),我不得不稍微修改merge-with中的逻辑。
评论者:michalmarczyk
我于2012年5月30日为{{zipmap}}创建了一个单独的工单,包括补丁,工单编号:CLJ-1005。
哎呀,如果我当时越界的话,很抱歉。如果这样能简化问题,我愿意从这次的补丁中移除那个变化——只需告诉我。
评论者:gshayban
附件中提供了另一种方法,即在协议加载后延迟合并,然后使用transducers。
评论者:michaelblume
看起来你在获取 m k 时做了两次——这不应该被放在局部变量中吗?
嗯,我在局部变量中说的“put”是不当的,‘throw’这个词的选择是错误的。
是的,那是对的——在 CLJ-700 提交后,将不会使用 get。
我们应该添加性能测试。合并两个、三个、很多个映射,以及不同大小的映射;对于 merge-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,所以它仍然是两次获取,对吗?看起来坚持使用 ::none 技巧会更有性能。
评论者:bronsa
这需要 if-let + find。
新的补丁解决了一些现有的担忧
CLJ-1458-transient-merge3.patch 移除愚蠢的内联宏,使用单例函数。
不错 =)
这应该附带测试。如果我们想保留合并到 MapEntry 的能力,我们应该对其进行测试。这与其说是补丁的弱点,不如说是现有测试的弱点。我在测试套件中看到了 merge 和 merge-with 几次使用,但我没有看到旨在测试它们行为的测试。