Как быстро просмотреть произвольное значение из HashSet? - PullRequest
0 голосов
/ 02 мая 2020

В настоящее время, когда я хочу получить любое значение из моего Hashset, я делаю это следующим образом:

my_set.iter().next().unwrap();

По сравнению с first или last методами из BTreeSet, это занимает очень много времени, и мои программы сильно страдают от этого. Кроме того, по соображениям производительности я не могу использовать BTreeSet, поскольку это значительно замедляет мою программу.

Есть ли способ получить любое значение из мой набор быстрее, чем я использую?

1 Ответ

1 голос
/ 02 мая 2020

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

Ниже приведено интуитивное доказательство того, что это невозможно.

Сначала давайте рассмотрим структуру HashSet. HashSet основан на хеш-таблице с ключом ha sh. Следующее использует эту хеш-таблицу, взятую из Википедии в качестве примера:

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

Рассмотрим случай где мы вставили три записи в примере, затем вызовем remove("John Smith") и remove("Lisa Smith"). Теперь мы запускаем этот мнимый алгоритм и получаем 521-9655. Как это сделать? Поскольку предполагается, что значения ha sh распределены равномерно, попытка исследовать записи 00, 01, ... должна работать так же эффективно, как и любой другой алгоритм, предполагая, что никакой другой информации не известно. Затем мы видим наихудший случай, когда нам нужно исследовать O (n) записей (в этом примере 15 проб), чтобы найти произвольную запись. Обратите внимание, что n - это число записей хеш-таблицы, которое линейно коррелирует с размером HashSet по коэффициенту загрузки хеш-таблицы (или максимальному размеру за все время, в зависимости от того, как реализация сокращает и перестраивает хеш-таблицу, когда слишком много элементы удаляются).

Таким образом, чтобы получить более быстрый алгоритм, мы должны хранить другую информацию о хеш-таблице, а не только исходную реализацию. Рассмотрим случай, когда мы индексируем указатели f (n), в которые могут быть вставлены записи. Как поддерживается этот индекс? Возможно, мы выполняем некоторые операции с insert() или remove(). Обновление индекса может быть тривиальным, когда записи вставляются, но если последовательно удаляются записи f (n) (

В заключение, предполагая, что мы не знаем, что с большей вероятностью будет вставлено / удалено, а ключи ha sh распределены равномерно, производительность просмотра произвольного значения должна быть либо O (n), либо иным образом влиять на производительность insert () / remove () по величине.

(Этот вывод может быть полезен. Простое предложение - ленивый рассчитать результат, предполагая, что вызовы remove () выполняются значительно реже по сравнению с поиском произвольных значений)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...