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

有关此主题的讨论链接: 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 能够这么做,我认为它们不需要像 Clojure 映射条目一样在 hasheq 中匹配。

时间

|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}}重载中不可能避免测试类型。

可以针对具有类型提示的字面量或给定的参数类型使用更具体的重载来加快哈希速度,因为编译器会提供适当的编译时间信息,以调用该重载。但是,在进行hash map / set操作时的“隐式”哈希过程中并不会获得任何加速。

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
参考: https://clojure.atlassian.net/browse/CLJ-1372(由wagjo报告)
...