ReSharper GetHashCodeオーバーライドに「397」が使用されるのはなぜですか?


150

多くの皆さんと同様に、私はReSharperを使用して開発プロセスをスピードアップしています。これを使用してクラスの等価メンバーをオーバーライドすると、GetHashCode()に対して生成されるコード生成は次のようになります。

    public override int GetHashCode()
    {
        unchecked
        {
            int result = (Key != null ? Key.GetHashCode() : 0);
            result = (result * 397) ^ (EditableProperty != null ? EditableProperty.GetHashCode() : 0);
            result = (result * 397) ^ ObjectId;
            return result;
        }
    }

もちろん自分のメンバーもいますが、なぜ397なのか知りたいのですが?

  • 編集:つまり、私の質問は、397の素数が素数であること以外に「特別な」何かがあるので、より適切に表現されますか?

回答:


166

おそらく、397は、結果変数をオーバーフローさせ、ハッシュのビットをいくらか混ぜ合わせるのに十分なサイズの素数であるため、ハッシュコードのより良い分布を提供します。同じ大きさの他の素数からそれを区別する397について特に特別なものは何もありません。


73
そして397は幸せです。私たちはみんな幸せになりたいのではないですか?
ラッセルB

2
さて、しかし、なぜそれが素数でなければならず、なぜそれがその正確な大きさでなければならないのですか?素数にする必要がある場合は、なぜ2または2147483647ではないのですか?私は素晴らしい突然変異を得ると思います(そしてこの乗算の唯一の理由は突然変異です)私たちは素数である必要はありません。乗算器には、比較的同じ数またはゼロと1が必要です。明示的なパターンがないことが望ましいです。397 = 110001101bは準拠しています。マグニチュードについてはまだわかりません。
Andriy K

5
ニックが言ったように、それについて特に特別なことは何もありません。そのサイズである必要はありません。これは、ハッシュを計算しているときに結果がオーバーフローするほど大きい数値です(GetHashCode()がInt32を返すため)。素数を選択することは分布に役立つだけであり、私は数学の学位を持っていないので、それを説明するつもりはありませんが、素数による乗算は、他の任意の数による乗算よりもよく分散される結果になります。
Ben Randall

16

リシャーパーが使用するハッシュは、FNVハッシュのバリアントのように見えます。FNVはしばしば異なる素数で実装されます。ここでは、FNVの適切な素数の選択についての議論があります

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.