Я ищу реализовать быструю, хорошо распределенную хэш-таблицу в C #. У меня возникают проблемы с выбором моей функции ограничения хеша, которая берет произвольный хеш-код и «ограничивает» его, чтобы его можно было использовать для индексации сегментов. Пока я вижу два варианта:
С одной стороны, вы можете убедиться, что в ваших корзинах всегда есть простое число элементов, и чтобы ограничить хеш, вы просто модулируете его по количеству блоков. Это, собственно, то, что делает словарь .NET . Проблема с этим подходом состоит в том, что использование% является чрезвычайно медленным по сравнению с другими операциями; если вы посмотрите на столах инструкции Agner Противотуманной ,
idiv
(который является ассемблерным кодом , который получает генерируется для%) имеет задержку выполнения команд ~ 25 циклов для новых процессоров Intel. Сравните это около 3 дляmul
, или 1 для битового опса , какand
,or
илиxor
.С другой стороны, у вас может быть число блоков, равное степени 2. Вам все равно придется вычислять модуль хэша, чтобы не пытаться индексировать вне массива, но на этот раз это будет дешевле , Поскольку для степеней 2
% N
справедливо& (N - 1)
, ограничение сводится к операции маскирования, которая занимает всего 1-2 цикла. Это сделано с помощью Google sparsehash . Недостатком этого является то, что мы рассчитываем на то, что пользователи будут предоставлять хорошие хэши; Маскировка хеша фактически обрезает часть хеша, поэтому мы больше не учитываем все биты хеша. Если хеш пользователя распределен неравномерно, например, заполнены только старшие биты или младшие биты постоянно одинаковы, тогда этот подход имеет гораздо более высокую частоту коллизий.
Я ищу алгоритм, который я могу использовать, который имеет лучшее из обоих миров: он учитывает все биты хэша, а также быстрее, чем использование%. Это не обязательно должен быть модуль, просто что-то, что гарантированно находится в диапазоне 0..N-1
(где N - длина сегментов) и имеет равномерное распределение для всех слотов. Существует ли такой алгоритм?
Спасибо за помощь.
(2^N +/- 1)
см stackoverflow.com/questions/763137/...