2024 年 Clojure 调查问卷中分享您的想法!

欢迎!有关如何使用本站点的更多信息,请参见关于页面

0
集合

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

43 个回答

0
_由 michalmarczyk 评论:

为了完整性,直接在hasheq中对{{Map}}, {{Set}}等进行分支,就像Jozef的原始补丁一样,在我的前一条评论中引入的微基准测试中会产生以下结果:

|xor|315.866626 ns|
|juhm|18.520133 µs|
0
_由 michalmarczyk 评论:

新的补丁(0006)去除了对{{Map.Entry}}的检查;相反,在{{Murmur3}}类中引入了两种方法来处理j.u.maps。

Java 映射条目实际上没有整合到Clojure中--您不能像向量一样使用它们,不能对它们调用{{seq}}等--因此,只要j.u.map与Clojure映射条目匹配,就不需要hasheq中匹配Clojure映射条目。

时间

|xor|233.341689 ns|
|juhm|9.104637 µs|
0
_由 michalmarczyk 评论:

检测Map/Iterable内联对异或基准测试结果影响不大,但使juhm哈希更快。这对我来说相当意外。无论如何,这里有一个新的补丁(0007)和时间

|xor|233.062337 纳秒|
|juhm|8.629149 微秒|
0

评论者:alexmiller

没有补丁时的等效时间是多少?

0
_由 michalmarczyk 评论:

这些在引入基准测试的注释中的表中列出——xor为148.128748纳秒,juhm为1.701640微秒。
0

评论者:alexmiller

如果我们用 instanceof 来代替直接使用 hasheq 为不同类型重载,会怎样?

0

评论者:michalmarczyk

重载方法是以静态方式解决的,因此在{{Object}}重载中避免类型检查是不可能的。

可以给参数类型使用类型提示或字面量来用更具体的重载来加速哈希,因为编译器会在适当的编译时信息下发出对该重载的调用。但是在映射/集合运算中的“隐式”哈希过程中不会有任何速度提升。

0

评论者:[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 的集合。

0

评论者:[email protected]

这个问题又出现了,详细情况在这里

0

评论者:mpenet

今天这问题又让我踩坑了(在找到解决办法之前浪费了很多时间)。我们能为1.7提供补丁吗?

0

评论者:alexmiller

据我所知,在考虑这个问题之前,我们仍在寻找一种在可接受的性能影响范围内的方法。

0

评论者:alexmiller

尽管我们不反对解决这个问题,但我们不希望以牺牲我们更关心的比较性能为代价来解决这个问题。目前,所有的提案都不符合这个标准。我将这个移至“待办事项”列表,但如果出现解决方案,我会将其拉出来。

0
...