Mengapa '397' digunakan untuk menimpa ReSharper GetHashCode?

150

Seperti banyak dari Anda, saya menggunakan ReSharper untuk mempercepat proses pengembangan. Saat Anda menggunakannya untuk mengganti anggota kesetaraan kelas, kode-gen yang dihasilkannya untuk GetHashCode () terlihat seperti:

    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;
        }
    }

Tentu saja saya memiliki beberapa anggota saya sendiri di sana, tetapi apa yang ingin saya ketahui adalah mengapa 397?

  • EDIT: Jadi pertanyaan saya akan lebih baik, apakah ada sesuatu yang 'istimewa' tentang bilangan prima 397 di luar itu menjadi bilangan prima?
programmer
sumber

Jawaban:

166

Mungkin karena 397 adalah bilangan prima dari ukuran yang cukup untuk menyebabkan variabel hasil meluap dan mencampurkan bit hash, memberikan distribusi kode hash yang lebih baik. Tidak ada yang istimewa tentang 397 yang membedakannya dari bilangan prima lain yang besarnya sama.

Nick Johnson
sumber
73
Dan 397 bahagia. Bukankah kita semua hanya ingin bahagia?
Russell B
2
Oke, tapi mengapa harus prima, dan mengapa harus sebesar itu? Jika harus prima, mengapa tidak 2 atau 2147483647? Saya kira untuk mendapatkan mutasi yang bagus (dan satu-satunya alasan untuk multiplikasi ini adalah mutasi) kita tidak perlu angka untuk menjadi prima. Kita membutuhkan multiplikator untuk memiliki angka atau angka yang relatif sama dan satu, lebih disukai tanpa pola eksplisit. 397 = 110001101b sesuai. Masih tidak yakin tentang besarnya.
Andriy K
5
Seperti kata Nick, tidak ada yang istimewa tentang itu. Itu TIDAK PERLU menjadi ukuran itu, itu hanya angka yang cukup besar bahwa ketika Anda menghitung hash hasilnya akan melimpah (karena GetHashCode () mengembalikan Int32). Memilih prime hanya membantu untuk distribusi, saya tidak memiliki gelar matematika jadi saya tidak akan mencoba dan menjelaskannya, tetapi perkalian dengan prime akan memiliki hasil yang lebih baik didistribusikan daripada perkalian dengan nomor arbitrer lainnya.
Ben Randall
16

Hash yang digunakan resharper terlihat seperti varian hash FNV . FNV sering diimplementasikan dengan bilangan prima yang berbeda. Ada diskusi tentang pilihan bilangan prima untuk FNV di sini .

kybernetikos
sumber