请分享您的想法,参加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 的特殊情况,就像它现在对 String 已经做的那样。

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

43 个答案

0
评论由:michalmarczyk

为了完整性,像 Jozef 的原始补丁中那样在 {{hasheq}} 中直接根据 {{Map}}, {{Set}} 等. 分支会导致以下在我的前一个评论中引入的微基准测试的时序

|xor|315.866626 纳秒|
|juhm|18.520133 微秒|
0
评论由:michalmarczyk

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

Java 映射条目实际上并没有集成到 Clojure 中 -- 你不能像向量一样使用它们,不能对它们调用 {{seq}} 等等。-- 因此,只要 j.u.maps 是合适的,我认为它们不需要在 hasheq 中匹配 Clojure 映射条目。

时序

|xor|233.341689 纳秒|
|juhm|9.104637 微秒|
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
参考: https://clojure.atlassian.net/browse/CLJ-1372(由wagjo报告)
...