2016-12-05 4 views
2

ケースクラスのハッシュコード部分でスカラーと混乱していることを学んでいます。Scala murmurハッシュとJavaネイティブハッシュ

私が見た限り、ケースクラスはtoString、equals、およびhashCodeの自動生成を提供しています。

伝統的な知恵は、Javaハッシュコードがネイティブ実装を使用することです。

しかし、Scalaでは、それはmurmur hash

私の質問を使用しています。

1)ハッシュコードはマシンに依存しているため、Javaにはネイティブのハッシュコードがありますが、スカラがハングを使用している場合、どのようにマシンに依存しませんか?

2)Scalaには通常のクラスとケースクラスがありますが、通常のクラスでも雑音ハッシュを使用していますか?

3)murmurハッシュが実際にポイント1の後に最も速い実装である場合、Javaはまだネイティブ実装を使用していますか?

答えて

8

MurmurHashは高速で高品質のハッシュです。 Scalaは、そのコレクション、タプル、ケースクラス、および他のほとんどのライブラリ提供オブジェクト(equalsと同様)に自動ハッシュコードを提供します。これらの多くはハッシュマップで使用されるため、適切なデフォルトハッシュを持つことが重要です。 MurmurHashがこれを提供します。私が知る限り、Javaハッシュはネイティブコードで実装されている場合でもマシンに依存しません。重要なことは、アルゴリズムがマシンからマシンまで同じであることです。スカラはバイトコードで完全に実装されているためです。Javaは、バイトコードにないもの(私はすべてをチェックしていませんでした)が慎重に行われたためです。

(少なくとも、何かを拡張する場合はjava.util.AbstractListですが、従来の知恵は間違っています。ネイティブ実装ではありません。イテレータのループは、内部の各メソッドのhashCodeメソッドを呼び出します。なぜあなたはそれがネイティブであることを望んでいますか?)

Scalaの通常のクラスは、MurmurHashを使わないようにhashCodeをオーバーライドしません。しかし、大文字小文字のクラスではないほとんどのライブラリクラスdoはMurmurHashを使用します。たとえば、すべての順序付けられたコレクションがそうです。 (順序に関係なく、順序に関係なく、MurmurHashを使用するのは適切ではありません)

MurmurHashは非常に高速ですが、可能な限り高速なハッシュではありません。 Javaは通常、ハッシュにx(n)*31 + x(n+1)型アルゴリズムを使用します。これはさらに高速です。残念ながら、それはかなり面倒なハッシュです。衝突するのはとても簡単です。また、MurmurHashは低オーバーヘッドと高速のオーバーヘッドの間で優れた妥協を見せていますが、大規模なオブジェクトでは他のハッシュ(XxHashやCityHashなど)を使用する方が高速です。したがって、誰もがMurmurHashをすべてのものに使うべきではありません。

しかし、より単純な典型的なJavaスタイルのハッシュの測定された欠陥のために、MurmurHashがScala用に選択されました。なぜJavaはそれを採用していないのですか?おそらくJavaは、より成熟した言語として、Scalaよりも遅く変化する傾向があり、誰もまだそれを熟知していない、または気になる人は既に独自のカスタムハッシングソリューションを使用しているからです。

+0

もし私がこの正しいscalaを理解していれば、それは最良の選択肢だったのでmurmur hashを選んでください。しかし、通常のscalaクラスがデフォルトのハッシュを選ぶのはなぜですか?おそらく互換性のために?カスタムハッシュ対デフォルトのJavaハッシュの線を描くことができません –

+1

デフォルトのハッシングはハッシングではなく、ちょうどメモリアドレスがハッシュコードとして再解釈されます(Javaの場合と同じです)。クラスのどの部分が重要であるかわからないときは、それは賢明です。ある意味でのequalsとhashCodeの定義は、あなたが重要と考えるものを表現します。 –