Scala murmur hash vs Java native hash

时间:2016-12-05 17:44:01

标签: java scala hash

我正在学习scala,并且对案例类的哈希码部分感到困惑。

据我所知,case类提供了toString,equals和hashCode的自动生成。

在java中,传统观点认为java hashcode使用本机实现。

但是在scala中它使用了murmur hash

我的问题。

1)Java具有本机哈希码,因为哈希码是依赖于机器的,但是如果scala使用杂音哈希那么它是如何与机器无关的?

2)Scala有常规类和案例类,普通类也使用杂音哈希吗?

3)如果murmur hash真的是第1点之后最快的实现,为什么java仍然使用本机实现?

1 个答案:

答案 0 :(得分:9)

MurmurHash是一种快速高质量的哈希。 Scala为其集合,元组,案例类和大多数其他库提供的对象(以及equals)提供自动hashCode,并且由于许多这些东西都在哈希映射中使用,因此拥有一个合适的默认哈希非常重要。 MurmurHash提供了这个。据我所知,Java哈希也不依赖于机器,即使有些情况下它们是用本机代码实现的。重要的是,从机器到机器的算法是相同的,Scala是因为它完全用字节码实现,而Java是因为任何不在字节码中的东西(我没有检查过所有东西!)都是小心翼翼地完成的。

(至少对于任何扩展java.util.AbstractList的东西,传统的智慧是错误的。它根本不是本机实现,只是迭代器上的循环,它调用内部每个东西的hashCode方法。但是JVM擅长这种循环和数学;为什么你希望它是原生的?)

Scala中的普通类不会覆盖hashCode,因此它们不使用MurmurHash。但是,大多数不是案例类的库类都使用MurmurHash - 例如,所有有序集合都可以。 (在订单上使用与订单无关的MurmurHash是不合适的,订单无关紧要。)

MurmurHash尽管速度很快,但并不是最快的哈希。 Java通常使用x(n)*31 + x(n+1)类型算法进行散列,这种算法甚至更快。不幸的是,它也是一个非常糟糕的哈希。碰撞很容易。此外,MurmurHash总体上在低开销和快速速度之间有一个很好的折衷,但是其他散列(例如XxHash或CityHash)对于大型对象来说可以更快,但代价是更多的启动开销。因此,每个人都应该将MurmurHash用于一切。

尽管如此,MurmurHash被选中用于Scala,因为在更简单的典型Java风格哈希中存在测量缺陷,并且它通常效果很好。为什么Java没有采用它?可能只是因为Java作为一种更成熟的语言,其变化速度往往比Scala慢,而且还没有人接触过它,和/或任何关心的人已经在使用他们自己的自定义散列解决方案。