Sto cercando di implementare una tabella hash veloce e ben distribuita in C #. Ho difficoltà a scegliere la mia funzione di hash-constraing che accetta un codice hash arbitrario e lo "vincola" in modo che possa essere utilizzato per indicizzare i bucket. Ci sono due opzioni che vedo finora:
-
Da un lato, puoi assicurarti che i tuoi bucket abbiano sempre un numero primo di elementi, e per limitare l'hash devi semplicemente farlo in base al numero di bucket. Questo è, in effetti, cosa fa il dizionario di .NET . Il problema con questo approccio è che l'utilizzo di% è estremamente lento rispetto ad altre operazioni; se si guarda Le tabelle di istruzioni Agner Fog ,
idiv
(che è il codice assembly generato per%) ha una latenza di istruzioni di ~ 25 cicli per i processori Intel più recenti. Confronta questo con circa 3 permul
, o 1 per operazioni bit a bit comeand
,or
oxor
. -
D'altra parte, puoi avere il numero di bucket sempre di potenza 2. Dovrai comunque calcolare il modulo dell'hash in modo da non tentare di indicizzare all'esterno dell'array, ma questo tempo sarà meno costoso. Poiché per le potenze del 2% di
% N
è appena& (N - 1)
, la limitazione viene ridotta a un'operazione di mascheramento che richiede solo 1-2 cicli. Questa operazione viene eseguita da sparsehash di Google . Il lato negativo di questo è che contiamo sugli utenti per fornire buoni hash; il mascheramento dell'hash esclude essenzialmente parte dell'hash, quindi non prendiamo in considerazione tutti i bit dell'hash. Se l'hash dell'utente è distribuito in modo non uniforme, ad esempio solo i bit più alti sono compilati oi bit inferiori sono sempre gli stessi, allora questo approccio ha un tasso di collisioni molto più alto.
Sto cercando un algoritmo che posso usare che ha il meglio di entrambi i mondi: prende in considerazione tutti i bit dell'hash ed è anche più veloce dell'utilizzo di%. Non ha necessariamente per essere un modulo, solo qualcosa che è garantito essere nell'intervallo 0..N-1
(dove N è la lunghezza dei bucket) e ha una distribuzione uniforme per tutti gli slot. Esiste un tale algoritmo?
Grazie per l'aiuto.