Я должен использовать для поиска HashSet или TreeSet для очень больших наборов данных?
У меня есть требование хранить от 2 до 15 миллионов учетных записей (которые являются String длиной 15) в структуре данных для целей поиска и проверки уникальности. Первоначально я планировал хранить их в HashSet, но я сомневаюсь, что скорость поиска будет медленной из-за коллизий хэшей и в конечном итоге будет медленнее, чем карта дерева (с использованием двоичного поиска).
Существует никакого требования в отношении данных, которые должны быть отсортированы. Я использую Java 7. У меня есть 64G система с 48G специально для этого приложение.
Этот вопрос не является дубликатом теста производительности HashSet и TreeSet , потому что этот вопрос касается производительности добавления элементов в Set и этот вопрос касается выполнения проверки существующего Set на наличие повторяющихся значений.
2 ответа:
Если у вас есть 48 ГБ выделенной памяти для ваших 2 млн до 15 млн записей, ваш лучший выбор, вероятно, использовать
HashMap<Key, Record>, Где ваш ключ являетсяIntegerилиStringв зависимости от ваших требований.Вы будете в порядке, если хэш-коллизии идут до тех пор, пока вы даете достаточно памяти для
Mapи имеете соответствующий коэффициент загрузки.Я рекомендую использовать следующий конструктор:
new HashMap<>(13_000_000);(на 30% больше, чем ожидаемое количество записей-которое будет автоматически расширено на РеализацияHashMapв2^24ячейки). Скажите вашему приложению, что этотMapбудет очень большим с самого начала, поэтому ему не нужно автоматически расти по мере его заполнения.
HashMapиспользует время доступаO(1)для своих членов, тогда какTreeMapиспользует время поискаO(log n), но может быть более эффективным с памятью и не нуждается в умной функции хэширования. Однако, если вы используете ключиStringилиInteger, Вам не нужно беспокоиться о разработке функции хэширования, и поиск по постоянному времени будет это будет огромным улучшением. Кроме того, еще одно преимуществоTreeMap/TreeSetэто упорядоченный порядок, о котором вы заявили, что вам все равно; используйтеHashMap.Если единственная цель списка-проверить наличие уникальных номеров счетов , то все, что я сказал выше, по-прежнему верно, но, как вы указали в своем вопросе, вы должны использовать
HashSet<String>, а неHashMap. Рекомендации по производительности и аргумент конструктора по-прежнему применимы.Дальнейшее чтение: HashSet и TreeSet тест производительности
Когда мы попытались сохранить 50 миллионов записей в HashMap с соответствующими параметрами инициализации, вставка начала замедляться, особенно после 35 миллионов записей. Переход на TreeMap давал постоянную производительность вставки и извлечения.
Наблюдение: TreeMap даст лучшую производительность, чем HashMap для большого входного набора. Для меньшего набора, конечно, HashMap даст лучшую производительность.