Saya mencari untuk mengimplementasikan tabel hash yang cepat dan didistribusikan dengan baik di C #. Saya mengalami masalah dalam memilih fungsi hash-constraining yang mengambil kode hash sembarang dan "membatasi" sehingga dapat digunakan untuk mengindeks ember. Ada dua opsi yang saya lihat sejauh ini:
Di satu sisi, Anda dapat memastikan ember Anda selalu memiliki jumlah elemen utama, dan untuk membatasi hash Anda cukup memodonya dengan jumlah ember. Inilah sebenarnya yang dilakukan oleh .NET's Dictionary . Masalah dengan pendekatan ini adalah bahwa menggunakan% sangat lambat dibandingkan dengan operasi lain; jika Anda melihat tabel instruksi Agner Fog ,
idiv
(yang merupakan kode rakitan yang dihasilkan untuk%) memiliki latensi instruksi ~ 25 siklus untuk prosesor Intel yang lebih baru. Bandingkan ini dengan sekitar 3 untukmul
, atau 1 untuk ops bitwise sepertiand
,or
, atauxor
.Di sisi lain, Anda dapat memiliki jumlah ember selalu menjadi kekuatan 2. Anda masih harus menghitung modulus hash sehingga Anda tidak berusaha untuk mengindeks di luar array, tetapi kali ini akan lebih murah . Karena untuk kekuatan 2
% N
hanya& (N - 1)
, pembatas direduksi menjadi operasi masking yang hanya membutuhkan 1-2 siklus. Ini dilakukan oleh Google sparsehash . Kelemahan dari ini adalah bahwa kami mengandalkan pengguna untuk menyediakan hash yang baik; menutupi hash pada dasarnya memotong sebagian dari hash, jadi kita tidak lagi memperhitungkan semua bagian dari hash. Jika hash pengguna tidak terdistribusi secara merata, misalnya hanya bit yang lebih tinggi yang diisi atau bit yang lebih rendah secara konsisten sama, maka pendekatan ini memiliki tingkat tabrakan yang jauh lebih tinggi.
Saya mencari algoritme yang dapat saya gunakan yang memiliki yang terbaik dari kedua dunia: ia mengambil semua bit hash ke dalam akun, dan juga lebih cepat daripada menggunakan%. Itu tidak harus harus menjadi modulus, hanya sesuatu yang dijamin berada dalam kisaran 0..N-1
(di mana N adalah panjang ember) dan memiliki distribusi yang merata untuk semua slot. Apakah ada algoritma seperti itu?
Terima kasih telah membantu.
(2^N +/- 1)
, lihat stackoverflow.com/questions/763137/…