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

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

43 个答案

0
_Comment made by: michalmarczyk_

为了完整性,直接在 hasheq 中对 {{Map}}, {{Set}} 等进行分支,就像 Jozef 最初的补丁那样,会在前一个评论中引入的微基准测试中产生以下时间。

|xor|315.866626 ns|
|juhm|18.520133 µs|
0
_Comment made by: michalmarczyk_

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

Java 映射条目并没有真正集成到 Clojure 中 -- 你不能像向量一样使用它们,不能调用 seq 等 -- 所以我认为只要 j.u.maps 与 Clojure 映射条目匹配,就不需要匹配 Clojure 映射条目中的 hasheq。

计时

|xor|233.341689 ns|
|juhm|9.104637 µs|
0
_Comment made by: michalmarczyk_

检查Map/Iterable内部不大会影响xor基准测试的结果,但会让juhm哈希更快。这对我来说相当令人惊讶。无论如何,这里有一个新的补丁(0007)和计时结果

|xor|233.062337 ns|
|juhm|8.629149 µs|
0

评论者:alexmiller

不带补丁的等价时间是什么?

0
_Comment made by: 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。这打破了在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 报告)
...