LevelDB против std :: map - PullRequest
       8

LevelDB против std :: map

6 голосов
/ 18 октября 2011

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

Я наткнулся на LevelDB и думаю об его использовании. Но у меня есть несколько вопросов.

  1. Документация LevelDB гласит, что она создана для пары ключ-строка (строка, строка). Означает ли это, что я не могу использовать для пользовательских пар ключ-значение?
  2. Кажется, разница между std::map и LevelDB в том, что LevelDB постоянен и std::map работает в памяти. Значит ли это, что узкое место дискового ввода / вывода будет более проблематичным для levelDB.

Более конкретно, кто-нибудь может объяснить, может ли LevelDB быть лучшим выбором, чем std::map?

PS: я пытался использовать hash_map s, но, похоже, он медленнее, чем std::map

Ответы [ 2 ]

8 голосов
/ 18 октября 2011

LevelDB просто делает что-то еще, кроме std :: map.

Вы действительно говорите, что хотите (высокую производительность) постоянство для std :: map?

  • посмотрите на std :: map с помощью специального распределителя. Выделите записи из области сопоставления памяти и используйте fsync, чтобы информация попадала на диск в стратегические моменты времени.

  • возможно, объединить это с EASTL (который может похвастаться более быстрым std :: map и процветает с пользовательскими распределителями - фактически у них нет распределителя по умолчанию)

  • посмотрите на настройку вашего hash_map (std :: unorderded_map); если hash_maps медленнее, вы должны изучить (a) loadfactor (b) настройка хеш-функции

  • И последнее, но не менее важное: оцените использование Boost Serialization для двоичной сериализации вашей карты (независимо от выбранной вами реализации). По моему опыту, производительность Boost Serialization является самой высокой.

2 голосов
/ 18 октября 2011

То, что вы сейчас делаете, это:

Скажем, у вас есть 1000000 записей в файле.Вы читаете весь файл в std :: map, это занимает около 1000000 операций.Вы используете find / insert для поиска и / или вставки элемента, это занимает логарифмическое время (около 20 сравнений).И теперь вы снова сохраняете весь файл, передавая все эти 1000000 записей обратно в файл.

Проблема в том, что вы абсолютно ничего не получаете от использования std :: map.std :: map дает вам быстрое время поиска (логарифмическое), но инициализация и сериализация всей карты для каждого поиска сводит на нет его преимущества.

Вам нужно либо перепроектировать свою программу, чтобы загрузить карту один раз взапустить и сериализовать его один раз в конце.Или, возможно, если вам нужна семантика базы данных, перейдите к реальной реализации базы данных.Я предлагаю использовать SQLite, хотя LevelDB может быть вам полезен.

...