C # hızlı, iyi dağıtılmış bir karma tablo uygulamak arıyorum. Ben rasgele bir karma kodu alır ve "bu" kovalar indekslemek için kullanılabilir "kısıtlama" benim karma kısıtlama işlevini seçme konusunda sorun yaşıyorum. Şimdiye kadar gördüğüm iki seçenek var:
Bir yandan, kovalarınızın her zaman asal sayıda elemente sahip olduğundan emin olabilirsiniz ve hash'ı sınırlamak için onu kova sayısına göre modüle edebilirsiniz. Aslında, .NET'in Sözlüğü bunu yapar . Bu yaklaşımdaki sorun,% kullanımının diğer işlemlere kıyasla son derece yavaş olmasıdır; Eğer bakarsak Agner Sis kullanım tabloları ,
idiv
(% için oluşturulmuş olur montaj kodudur) yeni Intel işlemciler için ~ 25 döngü bir talimat gecikme vardır. Yaklaşık 3 için bu karşılaştırınmul
gibi bitsel ops için, veya 1and
,or
ya daxor
.Öte yandan, kova sayısının her zaman 2 gücü olabilir. Hala karma modülünü hesaplamanız gerekecek, böylece dizinin dışında indeksleme girişiminde bulunmayacaksınız, ancak bu sefer daha ucuz olacak . 2'nin kuvvetleri
% N
için sadece& (N - 1)
kısıtlama olduğu için, kısıtlama sadece 1-2 döngü alan bir maskeleme işlemine indirgenir. Bu, Google'ın seyrekliği tarafından yapılır . Bunun dezavantajı, iyi karmalar sağlamak için kullanıcılara güvenmemiz; karmayı maskelemek aslında karmanın bir kısmını keser, bu yüzden artık karmanın tüm parçalarını hesaba katmıyoruz. Kullanıcının karması eşit olmayan bir şekilde dağılmışsa, örneğin yalnızca daha yüksek bitler doldurulur veya alt bitler tutarlı bir şekilde aynı ise, bu yaklaşım çok daha yüksek çarpışma oranlarına sahiptir.
Her iki dünyanın da en iyisine sahip kullanabileceğim bir algoritma arıyorum: karma tüm bitlerini hesaba katar ve% kullanmaktan daha hızlıdır. Mutlaka bir modül olmak zorunda değildir, sadece aralıkta olması garanti edilen bir şeydir 0..N-1
(burada N, kovaların uzunluğudur) ve tüm yuvalar için bile dağılıma sahiptir. Böyle bir algoritma var mı?
Yardım için teşekkürler.
(2^N +/- 1)
bkz. Stackoverflow.com/questions/763137/…