请分享您的观点,参加 2024 年 Clojure 状况调查!

欢迎!请查看 关于 页面,了解更多关于此功能的信息。

0
Collections

c.c/hash 总是使用 Java 集合的 hashCode,当与使用 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 添加一个特殊情况,就像它现在对 String 一样。

有关此主题在 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.maps 是这样,我认为它们不需要在 hasheq 中与 Clojure 映射项匹配。

时间

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

在行内检查 Map/Iterable 对 xor 基准结果的影响似乎不大,但会使 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]

这个问题再次出现了,详细信息请见 http://dev.clojure.org/jira/browse/DFRS-7

0

评论者:mpenet

今天这同样困扰了我(在解决问题之前浪费了很多时间)。我们是否会有针对 1.7 的补丁?

0

评论者:alexmiller

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

0

评论者:alexmiller

虽然我们不反对解决这个问题,但我们不希望以损害我们更关心的性能为代价,并且目前没有任何一个提交的方案符合这个标准。目前,我将它移至待办事项列表,如果出现解决方案,将会将其拉出来。

0
...