Estoy buscando implementar una tabla hash rápida y bien distribuida en C #. Tengo problemas para elegir mi función de restricción de hash que toma un código de hash arbitrario y lo "restringe" para que pueda usarse para indexar los cubos. Hay dos opciones que veo hasta ahora:
Por un lado, puede asegurarse de que sus cubos siempre tengan un número primo de elementos, y para restringir el hash, simplemente modúlelo por el número de cubos. Esto es, de hecho, lo que hace el Diccionario de .NET . El problema con este enfoque es que usar% es extremadamente lento en comparación con otras operaciones; Si observa las tablas de instrucciones de Agner Fog ,
idiv
(que es el código de ensamblado que se genera para%) tiene una latencia de instrucción de ~ 25 ciclos para los procesadores Intel más nuevos. Compare esto con alrededor de 3mul
, o 1 para operaciones bit a bit comoand
,or
oxor
.Por otro lado, puede hacer que el número de cubos sea siempre una potencia de 2. Todavía tendrá que calcular el módulo del hash para que no intente indexar fuera de la matriz, pero esta vez será menos costoso. . Dado que para potencias de 2
% N
es justo& (N - 1)
, la restricción se reduce a una operación de enmascaramiento que solo toma 1-2 ciclos. Esto lo hace sparsehash de Google . La desventaja de esto es que contamos con los usuarios para proporcionar buenos hashes; enmascarar el hash esencialmente corta parte del hash, por lo que ya no tomamos en cuenta todos los bits del hash. Si el hash del usuario está distribuido de manera desigual, por ejemplo, solo se completan los bits más altos o los bits más bajos son consistentemente iguales, entonces este enfoque tiene una tasa de colisiones mucho más alta.
Estoy buscando un algoritmo que pueda usar que tenga lo mejor de ambos mundos: toma en cuenta todos los bits del hash y también es más rápido que usar%. No necesariamente tiene que ser un módulo, solo algo que se garantiza que esté en el rango 0..N-1
(donde N es la longitud de los cubos) y tiene una distribución uniforme para todas las ranuras. ¿Existe tal algoritmo?
Gracias por ayudar.
(2^N +/- 1)
, consulte stackoverflow.com/questions/763137/…