Я хочу впровадити швидку, добре розподілену хеш-таблицю в C #. У мене виникають проблеми з вибором функції обмеження хешу, яка приймає довільний хеш-код і "обмежує" його, щоб його можна було використовувати для індексації відра. Дотепер я бачу два варіанти:
З одного боку, ви можете переконатися, що у ваших відрах завжди є проста кількість елементів, а щоб обмежити хеш, ви просто змодулюєте його на кількість відра. Це, власне, те, що робить словник .NET . Проблема такого підходу полягає в тому, що використання% є надзвичайно повільним порівняно з іншими операціями; якщо ви подивитеся на таблиці інструкцій Agner Fog ,
idiv
(який є кодом складання, який генерується на%), затримка інструкцій становить ~ 25 циклів для новіших процесорів Intel. Порівняйте це близько 3 дляmul
, або 1 для бітового опса , якand
,or
абоxor
.З іншого боку, ви можете мати кількість відра завжди потужністю 2. Вам все одно доведеться обчислювати модуль хешу, щоб не намагатися індексувати поза масивом, але цього разу це буде дешевше . Оскільки для потужностей 2
% N
просто& (N - 1)
, обмеження зводиться до операції маскування, яка займає лише 1-2 цикли. Це робиться з-за рідкості Google . Мінус цього полягає в тому, що ми розраховуємо на те, щоб користувачі надавали хороші хеши; маскування хеша по суті відрізає частину хешу, тому ми більше не беремо до уваги всі біти хешу. Якщо хеш користувача розподілений нерівномірно, наприклад, заповнюються лише більш високі біти або послідовно нижчі біти, то такий підхід має набагато більшу швидкість зіткнень.
Я шукаю алгоритм, з яким я можу використовувати найкращі з обох світів: він враховує всі біти хешу, а також швидший, ніж використання%. Це не обов'язково має бути модулем, просто те, що гарантовано знаходиться в діапазоні 0..N-1
(де N - довжина відра) і має рівномірний розподіл для всіх слотів. Чи існує такий алгоритм?
Дякуємо за допомогу.
(2^N +/- 1)
см stackoverflow.com/questions/763137 / ...