Какой контейнер выбрать

#c #boost #map #containers

#c #повышение #словарь #контейнеры

Вопрос:

Я думал о сохранении некоторых объектов … и теперь я не знаю, что выбрать.

Итак, теперь у меня есть такой код:

 std::map<std::strin&, Object*&&t; mObjects;
  

Но, как мне говорили здесь ранее, это происходит медленно из-за выделения std::strin& при каждом поиске, поэтому ключ должен быть целочисленным.

Почему я выбрал std::strin& в качестве ключа? Потому что очень легко получить доступ к объектам по их имени, например:

 mObjects["SomeObj"];
  

Итак, моя первая идея такова:

 std::map<int, Object*&&t; mObjects;
  

а ключ — это CRC имени объекта:

 mObjects[CRC32("SomeObject")];
  

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

Есть идеи о контейнере, который я могу использовать?

Итак, еще раз, основные моменты:

  • Доступ к объектам по строке, но ключ должен быть целым числом, а не строкой
  • Сортировка объектов на карте с помощью некоторой функции

p.s. использование boost допустимо.

Комментарии:

1. Вы сначала измеряли производительность с помощью строковых ключей, прежде чем говорить, что она медленная?

2. Требуются ли строки из-за ограничений времени выполнения или все значения известны во время компиляции и могут быть заменены константой, такой как: const int SOME_OBJECT = 1; ... mObject[SOME_OBJECT] ...

3. @thanatos нет, они не могут. Существует около 1000 объектов.

4. Можете ли вы использовать unordered_map ?

5. Вы могли бы изучить Boost. MultiIndex, это позволяет вам индексировать элементы различными способами в одном контейнере. Вы могли бы использовать хэшированный индекс для быстрого поиска и упорядоченный индекс для сортировки.

Ответ №1:

Я не могу сказать наверняка, но вы всегда обращаетесь к элементам на карте с помощью литеральной строки? Если это так, то вам следует просто использовать последовательно перечисленные значения с символическими именами и соответствующим размером vector .

Предположение, что вы не будете знать имен до тех пор, пока во время выполнения не появится 1000 элементов на карте, кажется действительно небольшим, чтобы поиск мог быть узким местом. Уверены ли вы, что проблема с производительностью заключается в поиске? Вы профилировали, чтобы убедиться, что это так? В общем, использование наиболее интуитивно понятного контейнера приведет к улучшению кода (потому что вы сможете легче понять алгоритм).

Подразумевает ли ваш комментарий о построении строк, что вы снова и снова передаете C-строки в функцию find? Постарайтесь избежать этого, последовательно используя std::strin& в своем приложении.

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

Комментарии:

1. Как насчет map. Я вызываю поиск примерно для ~ 250 объектов каждые ~ 11 мс. Это небольшое число? И все они также повторяются каждые ~ 11 мс. Я думаю, что boost::multiindex — это то, что мне нужно.

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

3. @Ockonal Вы не используете std::find на своей карте, не так ли?