次のコードがあります。
int i = 1;
Console.WriteLine(i.GetHashCode()); // outputs => 1
これは理にかなっており、sbyteとshortを除くC#のすべての整数型でも同じことが起こります。あれは:
sbyte i = 1;
Console.WriteLine(i.GetHashCode()); // outputs => 257
どうしてこれなの?
そのメソッドのソース(SByte.GetHashCode
)は
public override int GetHashCode()
{
return (int)this ^ ((int)this << 8);
}
理由については、Microsoftの誰かがそれをよく知っています。
はい、それはすべて価値の分配についてです。GetHashCodeメソッドの戻り型はsbyte型のintであるため、値は257の間隔で分散されます。これと同じ理由で、long型は衝突になります。
その理由は、おそらくハッシュ値のクラスタリングを回避するために行われるためです。
GetHashCode
ドキュメントが言うように:
最高のパフォーマンスを得るには、ハッシュ関数がすべての入力に対してランダムな分布を生成する必要があります。クラスに適切なハッシュ関数を提供すると、それらのオブジェクトをハッシュテーブルに追加するパフォーマンスに大きな影響を与える可能性があります。ハッシュ関数が適切に実装されているハッシュテーブルでは、要素の検索に一定の時間がかかります(たとえば、O(1)操作)。
また、この優れた記事で説明されているように:
ガイドライン:ハッシュコードの分布は「ランダム」でなければなりません「ランダム分布」とは、ハッシュされるオブジェクトに共通性がある場合、生成されるハッシュコードに同様の共通性があってはならないことを意味します。たとえば、ポイントの緯度と経度を表すオブジェクトをハッシュしているとします。このような場所のセットは、「クラスター化」されている可能性が非常に高くなります。たとえば、場所のセットがほとんど同じ都市の家、またはほとんど同じ油田のバルブなどである可能性は高いです。クラスター化されたデータがクラスター化されたハッシュ値を生成する場合、使用されるバケットの数が減り、バケットが非常に大きくなるとパフォーマンスの問題が発生する可能性があります。