欢迎!有关如何使用本站点的更多信息,请参见关于页面。
c.c/hash始终使用hashCode为Java集合生成哈希值,这在使用Murmur3进行哈希运算的Clojure集合进行比较时是不兼容的。
user=> (== (hash (java.util.ArrayList. [1 2 3])) (hash [1 2 3])) false user=> (= (java.util.ArrayList. [1 2 3]) [1 2 3]) true
修复此问题的一种方法是向Util/hasheq中添加一个特殊的案例来处理java.util.Collections,就像现在处理Strings一样。
有关此主题的Clojure群组讨论链接: https://groups.google.com/forum/#!topic/clojure/dQhdwZsyIEw
评论者:alexmiller
没有补丁时的等效时间是多少?
如果我们用 instanceof 来代替直接使用 hasheq 为不同类型重载,会怎样?
评论者:michalmarczyk
重载方法是以静态方式解决的,因此在{{Object}}重载中避免类型检查是不可能的。
可以给参数类型使用类型提示或字面量来用更具体的重载来加速哈希,因为编译器会在适当的编译时信息下发出对该重载的调用。但是在映射/集合运算中的“隐式”哈希过程中不会有任何速度提升。
评论者:[email protected]
当我将 Factual/skuld 从 1.5.1 升级到 1.6 时,clojure.data.fressian 序列化将 c.l.PersistentHashSet 集合序列化为 java.util.HashSet。这破坏了https://github.com/Factual/skuld/blob/b720feb142e6d274e85be208dc1d6d8634801719/test/skuld/net_test.clj#L8-L29中的等性检查,因为我们正在比较包含 PersistentSet 的原始集合和序列化后以及反序列化后的包含 HashSet 的集合。
这个问题又出现了,详细情况在这里。
评论者:mpenet
今天这问题又让我踩坑了(在找到解决办法之前浪费了很多时间)。我们能为1.7提供补丁吗?
据我所知,在考虑这个问题之前,我们仍在寻找一种在可接受的性能影响范围内的方法。
尽管我们不反对解决这个问题,但我们不希望以牺牲我们更关心的比较性能为代价来解决这个问题。目前,所有的提案都不符合这个标准。我将这个移至“待办事项”列表,但如果出现解决方案,我会将其拉出来。