2016-11-20 3 views
1

私は、他のオブジェクトから取得したハッシュコードは、x86またはx64用に構築したときとは異なることに気付きました。 今まで私はこのような自分自身のハッシュ関数のほとんどを実装している:私は、x86または64用にビルドするかどうかによって、オブジェクトから異なるハッシュコードを取得することに気付きました。

int someIntValueA; 
int someIntValueB; 

const int SHORT_MASK = 0xFFFF; 
public override int GetHashCode() 
{ 
    return (someIntValueA & SHORT_MASK) + ((someIntValueB & SHORT_MASK) << 16); 
} 

が長いの値を格納し、それからハッシュコードは私の64ビットシステム上だけでなく、より広い範囲を与えてきます、またはこれは悪い考えですか?

public override int GetHashCode() 
{ 
    long maybeBiggerSpectrumPossible = someIntValueA + (someIntValueB << 32); 
    return maybeBiggerSpectrumPossible.GetHashCode(); 
} 
+0

あなたはまだ 'int'を返すので、より広い範囲を与えることはありません。 – Ryan

+0

@Ryanそれは私が求めていることです:intはいつもそしていつまでもintですか?それとも、いくつかの状況下ではint64/longになりますか? – user3488765

+1

これはあなたが尋ねた質問ではありません。その質問に対する答えは次のとおりです。C#intはInt32の同義語であり、ストーリーの終わりです。ポインタサイズの整数は 'IntPtr'であり、あなたはC#で数学を行うことを許可していません。 –

答えて

7

いいえ、それははるかに悪くなります。

あなたのint値は通常、短く、-30000から+30000の範囲であるとします。さらに、それらのほとんどが0から1000の中間付近にあるとします。これはかなり一般的です。あなたの最初のハッシュコードでは、となります。ハッシュコードの両方のintのビットは互いに干渉しません。典型的な条件下では衝突回数はゼロです。

しかし、あなたが長い間あなたのトリックを行うとき、GetHashCodeの長い実装が何かを頼りにしています。これは、x32または下位32ビットの上位32ビットです。ですから、あなたの新しい実装は、遅い書き方のint1^int2です。これは、典型的なシナリオではほぼすべてゼロビットであり、そのために全面衝突します。

1

あなたが提案するアプローチは、それ以上の改善はしません。しかし

...

SpookyHashは、著者が考えていた数学のワークアウト時に、何が64ビットシステムで、高速になるので、64ビットシステムで特に急速に動作するように設計例えば、xxHashは32を持っています32ビットおよび64ビットの計算でそれぞれ同等の品質のハッシュをより高速に提供するように設計されています。

異なるマシンで異なる算術演算の違いを利用する一般的な考え方は有効です。

ハッシュ計算で大きな中間記憶域を使用するという一般的な考え方も、これらの余分なビットが後続の操作に入る限り、有効な1つですです。

非常に一般的なレベルでは、特定の実装ではそれが実現しない場合でも、答えは「はい」です。

今実際には、ハッシュコード実装を書くときに座っているとき、これについて心配する必要がありますか?

まあそれに依存します。しばらくの間、私はSpookyHashのようなアルゴリズムを使用することについて非常に強気でした。ハッシュが大量のソースデータに基づいている場合、(32ビットシステムでさえ)非常にうまく機能します。しかし、一方では、特に小さなハッシュベースのセットや辞書で使用すると、より良いことがあります。だから1つの解決策にはすべての答えはありません。 2つの入力整数を使うことで、初期解はxxHashやSpookyHashのような超功績アルゴリズムを打ち負かす可能性が高くなります。シフトよりも回転するのが>> 16であれば、おそらくもっとうまくいくかもしれませんが(それはいくつかのジッタが最適化されているという事実ですが)、64ビット版と32ビット版はまったく同じです。

64ビットと32ビットで別のアプローチをとって大きな改善が見られる場合は、特に、blittable形式の場合(例えば、stringまたはbyte[] )は、フレームワークに応じてlong*またはint*でアクセスできます。

ビット数の問題を無視することはできますが、「このハッシュコードは非常に多くのものを使って答えを得る必要があります。 、おそらくだと思います。

関連する問題