Leveldb против Std :: map
-
25-10-2019 - |
Вопрос
В нашем приложении мы используем std::map
Чтобы сохранить (ключ, значение) данные и использовать сериализацию для хранения этих данных на диске. При таком подходе мы обнаруживаем, что диск ввода/вывод является узким местом производительности, и поиск значений с использованием ключа не очень быстро.
Я наткнулся на leveldb и думаю об использовании его. Но у меня есть несколько вопросов.
- В документации LevelDB говорится, что она сделана для пары значений ключей (строка, строка). Значит ли это, что я не могу использовать для пользовательских паров значений ключей?
- Кажется разницей между
std::map
и leveldb - это то, что leveldb устойчив иstd::map
работает в памяти. Значит ли это, что узкое место ввода/вывода будет более проблематичным для LevelDB.
Более конкретно может кто -нибудь, пожалуйста, объясните, может ли LevelDB быть лучшим выбором, чем std::map
?
PS: я пытался использовать hash_map
S но это кажется медленнее, чем std::map
Решение
LevelDB просто делает что -то другое, кроме Std :: Map.
Вы действительно говорите, что хотите (высокая производительность) настойчивость для Std :: Map?
Посмотрите на Std :: Map с пользовательским распределителем. Распределите записи из области памяти, отображаемая и используйте FSYNC, чтобы гарантировать, что информация попадает на диск в стратегические моменты времени.
Возможно, объедините это с Eastl (которая может похвастаться более быстрой Std :: Map и процветает с пользовательскими распределителями - на самом деле у них нет распределения по умолчанию)
Посмотрите на настройку вашего hash_map (std :: unoromonded_map); Если hash_maps медленнее, вы должны изучить (а) настройку функции хэш -функции (б)
И последнее, но не менее важное: оценить использование сериализации BOOST для бинарной сериализации вашей карты (любая реализация, которую вы выбрали). По моему опыту повысить производительность сериализации является главным в законопроекте.
Другие советы
То, что вы делаете сейчас, это:
Скажем, у вас есть 1000000 записей в файле. Вы читаете весь Файл в std :: map, это занимает около ~ 1000000 операций. Вы используете Find/INSERT, чтобы найти и/или вставить элемент, это требует логарифмического времени (около 20 сравнений). И теперь вы снова сохраняете весь файл, передавая все эти 1000000 записей обратно в файл.
Проблема в том, что вы абсолютно ничего не выигрываете от использования Std :: Map. Std :: Map дает вам быстрое время поиска (логарифмическое), но инициализация и сериализация всей карты на каждый поиск улаживает его преимущества.
То, что вам нужно, - это либо перепроектирование, которую вы программируете, поэтому вы будете загружать карту один раз при запуске, и один раз сериализуйте ее при завершении. Или, возможно, если вам нужна семантика базы данных, перейдите на реальную реализацию базы данных. Я предлагаю использовать SQLite, хотя LevelDB может быть таким же хорошим для вас.