структура данных для хранения массива строк в памяти - PullRequest
3 голосов
/ 30 августа 2010

Я рассматриваю структуру данных для хранения большого массива строк в памяти.Строки будут вставлены в начале программы и не будут добавлены или удалены во время работы программы.Важнейшим моментом является то, что процедура поиска должна быть максимально быстрой.Экономия памяти не важна.Я склоняюсь к стандартной структуре hash_set из стандартной библиотеки, что позволяет искать элементы в структуре примерно с постоянным временем.Но это не гарантировано, что это время будет коротким.Кто-нибудь предложит лучшее стандартное решение?

Большое спасибо!

Ответы [ 7 ]

3 голосов
/ 30 августа 2010

Попробуйте Дерево префиксов

Trie лучше, чем Binary Search Tree для поиска элементов. По сравнению с хеш-таблицей вы могли видеть этот вопрос

2 голосов
/ 30 августа 2010

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

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

Практически никогда не бывает так, чтобы скорость была единственным критическим моментом.

1 голос
/ 30 августа 2010

Есть, например, Google-sparsehash . Он включает в себя реализацию плотного хэш-набора / карты (пере), которая может работать лучше, чем стандартная библиотека хэш-набора / карты. Смотрите производительность . Убедитесь, что вы используете хорошую хэш-функцию. (Мой субъективный голос: murmur2.)

Строки будут вставлены в начало программы и не будет быть добавленным или удаленным во время работы программы.

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

** Применяется стандартный отказ от ответственности: в зависимости от варианта использования, реализаций, набора данных, фазы Луны и т. Д. Теоретические ожидания могут отличаться от наблюдаемых результатов из-за факторов, не учитываемых (например, кэш-памяти и задержки памяти, временная сложность определенных машинных инструкций и т. д.). *

0 голосов
/ 30 августа 2010

Ваша лучшая ставка будет выглядеть следующим образом:

  1. Построение вашей структуры:
    1. Вставьте все свои строки (символы *) в массив.
    2. Сортировкамассив лексикографически.
  2. Lookup
    1. Использование двоичного поиска в вашем массиве.

Это поддерживает локальность кэша, обеспечивает эффективный поиск (будет искать в пространстве ~ 4 миллиардов строк с 32 сравнениями), и очень прост в реализации.Не нужно увлекаться попытками, потому что они сложны и медленнее, чем кажутся (особенно если у вас длинные строки).

Случайный sidenote: в сочетании с http://blogs.msdn.com/b/oldnewthing/archive/2005/05/19/420038.aspx, вы не остановитесь!

0 голосов
/ 30 августа 2010

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

Дополнительный метод, который может сохранить поиск в таблице строк, заключается в использовании атомов : каждый раз, когда вы читаете строкучто вы знаете, что собираетесь искать в таблице, сразу же искать ее и сохранять указатель на нее (или индекс в структуре данных) вместо хранения строки.Таким образом, проверка равенства двух строк - это простой указатель или целочисленное равенство (и вы также экономите память, сохраняя каждую строку один раз).

0 голосов
/ 30 августа 2010

Что ж, если вы действительно хотите массив , а не ассоциативный контроллер , как вы упомянули, стратегия выделения, упомянутая в блоге Раймонда Чена , будет такой:эффективный.

0 голосов
/ 30 августа 2010

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

...