Java: «простое» число или «сила двух» в качестве размера HashMap?

Многие книги и учебники говорят, что размер хеш-таблицы должен быть простым, чтобы равномерно распределять ключи во всех ведрах. Но Java HashMap всегда использует размер, который имеет силу в два раза. Не следует ли использовать премьер? Что лучше, «премьер» или «сила двух» в качестве размера hash-таблицы?

Использование мощности двух эффективно маскирует верхние биты хеш-кода. Таким образом, hash-функция некачественного качества может проявиться особенно плохо в этом сценарии.

HashMap Java смягчает это, не hashCode() реализации hashCode() объекта и применяя второй уровень hashирования к его результату :

Применяет дополнительную хеш-функцию к заданному hash-коду, который защищает от hash-функций низкого качества. Это важно, потому что HashMap использует hash-таблицы с длиной в две строки, которые в противном случае сталкиваются с конфликтами для hash-кодов, которые не отличаются в младших битах.

Если у вас хорошая hash-функция или что-то похожее на то, что делает HashMap , не имеет значения, используете ли вы простые числа и т. Д., Как размер таблицы.

Если, с другой стороны, хеш-функция имеет неизвестное или низкое качество, то использование простого номера будет более безопасной ставкой. Тем не менее, он будет делать таблицы с динамическим размером, чтобы реализовать, так как внезапно вам нужно будет создавать простые числа вместо того, чтобы просто умножать размер на постоянный коэффициент.

Стандартная реализация HashMap имеет hash метод, который перехватывает hash-код вашего объекта, чтобы избежать этой ошибки. Комментарий перед методом hash() :

 /** * Retrieve object hash code and applies a supplemental hash function to the * result hash, which defends against poor quality hash functions. This is * critical because HashMap uses power-of-two length hash tables, that * otherwise encounter collisions for hashCodes that do not differ * in lower bits. Note: Null keys always map to hash 0, thus index 0. */ 

Единственный способ узнать, что лучше между простым и сильным, – это сравнить его.

Много лет назад, когда я писал ассемблер, чья производительность сильно зависела от поиска символа talbe, я тестировал это, используя большой блок сгенерированных идентификаторов. Даже с наивным отображением я обнаружил, что мощность двух, как и ожидалось, имела менее равномерное распределение и более длинные цепочки, чем простое количество кодов с одинаковым размером. Он по-прежнему работает быстрее, из-за скорости выбора ковша с помощью маскировки бит.

Я сильно подозреваю, что разработчики java.util не прибегли бы к дополнительному hashированию и силе двух, не сравнивая его с использованием простого количества ведер. Это очень очевидная вещь, когда нужно создавать хешированную структуру данных.

По этой причине я уверен, что размер перефразировки и мощности-два дает лучшую производительность для типичных hash-карт Java, чем простое количество ковшей.

С точки зрения производительности / расчета времени измерения мощности двух размеров могут быть рассчитаны с помощью только маскирования бит, которая быстрее, чем целочисленное деление, которое в противном случае потребовалось бы.

Вероятно, вы должны использовать таблицы хеш-размера, если вы используете квадратичное зондирование для разрешения конфликтов. Если у вас есть таблица с обычным размером, квадратичное зондирование ударит половину записей, меньше, если оно не является простым. Таким образом, вы можете найти подходящее место для хранения записи, даже если ваша хеш-таблица меньше половины. Поскольку hash-карты Java не используют квадратичное зондирование, нет необходимости использовать простые числа в качестве размера.

Interesting Posts

Являются ли msa.exe и ygh.exe действительно вредоносными программами и что еще нужно сделать для очистки ПК?

IE пересекает псевдоэлемент CSS?

Проблемы с рендерингом в Android Studio v 1.1 / 1.2

Поддерживает ли C # проектное пространство имён по умолчанию, как VB.NET?

RAMDISK OS? Установка Windows 10 на ramdisk

NuGet Behind Proxy

Использовать reflection для вызова переопределенного базового метода

AudioObjectGetPropertyData для получения списка устройств ввода

Изменив жесткий диск на ssd, могу ли я перенести содержимое, чтобы я мог переключать диски без хлопот?

Selenium с использованием Java. Путь к исполняемому файлу драйвера должен быть задан с помощью свойства webdriver.gecko.driver

Блокировать доступ в Интернет ко всем программам, за исключением белых списков

Как вы убиваете Thread в Java?

Групповой массив объекта, вложенного в некоторые из ключей с определенными именами

Есть ли у Java указатели?

Ошибка , когда я пытался обновить приложение

Давайте будем гением компьютера.