评论由:mikera
Rich,这些是很好的见解 - 你有一个你用作代表实际代码的基准测试吗?
我认为如果我们能够避免调用站点出现 megamorphic(巨大变形)的情况是很好的,尽管考虑到已经存在的多种 IPersistentVector 类型(例如 MapEntry、PersistentVector、SubVector 以及任何库定义的 IPersistentVector 实例,如 clojure.core.rrb-vector),我认为这方面的船已经开走了。因此,JVM 通常无法证明特定的 IPersistentVector 接口调用是 monomorphic 的,这时才会出现真正的优化。
在我处理的大部分现实世界代码中,相同的尺寸/类型的向量会被重复使用(例如:遍历映射条目、处理大小为 N 的序列),因此在这种情况下,我们应该能够依赖多态的内联缓存来正确地完成工作。
为 0 到 4 的大小使用单个 Tuple 类很有趣,但我忍不住想,从性能提升的角度来看,这可能更多地来源于许多代码都做类似 (reduce conj (link: )).. 或者 transient 等价的操作,这对 Tuple 来说是一个特别糟糕的使用场景,至少是从调用站点缓存的角度来看。可能有一种更好的方法来优化这种场景,而不是简单地尝试让 Tuple 更快……例如,对 Tuple0 调用 asTransient() 可能会直接切换到 PersistentVector 实现中。