Мне интересно узнать производительность multi_index_container для следующего варианта использования:
struct idx_1 {};
struct idx_2 {};
typedef multi_index_container<
Object,
indexed_by<
// Keyed by: idx1
hashed_unique<
tag<idx_1>,
unique_key >,
// Keyed by: (attribute1, attribute2 and attribute3)
ordered_non_unique<
tag<idx_2>,
composite_key<
Object,
attribute1,
attribute2,
attribute3 > >
>
> ObjectMap;
Мне нужна карта для сохранения объекта, а количество объектов должно быть более 300 000. при этом каждый объект имеет 1 уникальный ключ и 3 атрибута. Детали ключей:
- уникальный ключ является "уникальным" как имя
- каждый атрибут имеет только несколько возможных значений, скажем, всего 16 комбинаций. Таким образом, с 300 000 объектов каждая комбинация будет иметь список из 300 000/16 объектов.
- attribute1 необходимо время от времени изменять с одного значения на другое значение
- поиск объектов всегда выполняется с помощью unique_key, в то время как композитный ключ используется для итерации объектов с одним или несколькими атрибутами.
Для такого случая использования multi_index_container очень хорошо подходит, так как мне не нужно поддерживать несколько карт независимо друг от друга. Я считаю, что для части уникального ключа хорошим кандидатом является hashed_unique, а не order_unique.
Но меня крайне не устраивает часть «ordered_non_unique». Я не знаю, как это реализовано в boost. Я предполагаю, что это поможет поддерживать список объектов в одном списке для каждой комбинации, аналогичной unordered_map (простите меня, если это слишком наивно!). Если это так, изменение атрибута существующего объекта будет большой проблемой, поскольку для этого требуется: 1) просмотреть длинный список объектов для конкретной комбинации 2) выполнить равное сравнение 3) и переместить целевую комбинацию.
шаги, которые я подозреваю с высокой задержкой:
ObjectMap objects_;
auto& by_idx1 = objects_.get<idx1>();
auto it = by_idx1.find(some_unique_key);
Object new_value;
by_idx1.modify(it, [&](const Object& object) {
object = new_value;
});
Меня беспокоит то, что последняя функция «изменить» имеет какое-то поведение лайнера, как указано, для прохождения некоторого потенциально длинного списка объектов в одной комбинации...