Clojure 2024 年调查中分享您的看法!

欢迎!请查看关于页面,了解更多关于这是如何工作的信息。

0
Collections

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 添加一个特殊案例,就像现在为 String 那样。

有关此主题在 Clojure 群组中的讨论链接:https://groups.google.com/forum/#!topic/clojure/dQhdwZsyIEw

43 答案

0
_评论者:michalmarczyk_

为了完整性,正如 Jozef 的原始补丁一样,在 hasheq 中直接根据 {{Map}}, {{Set}} 等. 分支,如在先前的评论中引入的微基准测试中的以下时间:

|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 ns|
|juhm|8.629149 µs|
0

评论者:alexmiller

补丁前的等效性能如何?

0
_评论者:michalmarczyk_

它们列在介绍基准测试的注释中的表格中 -- xor为148.128748 ns,juhm为1.701640 µs。
0

评论者:alexmiller

如果我们不是使用instanceof而是覆盖为不同类型的hasheq会怎样?

0

评论者:michalmarczyk

重载方法是在静态中解析的,所以在{{Object}}重载中无法避免测试类型。

如果给定类型提示或字面量,可以使用更具体的重载来加快特定类型的哈希速度,因为编译器会根据编译时的适当信息发出对该重载的调用。然而,在hash map / set操作中的"隐式"哈希将不会提高速度。

0

评论者:[email protected]

在将Factual/skuld从1.5.1升级到1.6时,clojure.data.fressian序列化了c.l.PersistentHashSet集合为java.util.HashSet。这破坏了在以下链接中的等价性检查:[GitHub链接](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
参考:[GitHub链接](https://clojure.atlassian.net/browse/CLJ-1372)(由wagjo报告)
...