boost multi_index_container的性能

时间:2014-10-23 05:17:57

标签: c++ performance boost-multi-index

我很想知道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个属性。键的细节:

  1. 唯一键是&#34;唯一&#34;作为名称
  2. 每个属性只有几个可能的值,比如只有16个组合。因此,对于300,000个对象,每个组合将具有300,000/16个对象的列表
  3. attribute1需要偶尔从一个值修改为另一个值
  4. 始终通过unique_key完成对象查找,而composite_key用于迭代具有一个或多个属性的对象
  5. 对于这样的用例,multi_index_container是非常合适的,因为我不需要独立维护多个地图。对于唯一的关键部分,我相信hashed_unique是一个很好的候选者而不是ordered_unique。

    但我非常不满意&#34; ordered_non_unique&#34;部分。我不知道如何在提升中实施。我猜它会在每个组合的单个列表中维护一个对象列表,类似于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;
    });
    

    我关心的是,是否最后修改&#34;函数具有一些线性行为,如下所述,可以在一个组合下查看一些潜在的长对象列表...

2 个答案:

答案 0 :(得分:0)

由于这是一段非常具体的代码,我建议您使用大量的实际数据对其进行基准测试和分析。

答案 1 :(得分:0)

正如法比奥的评论,你最好的选择是分析案例并查看结果。无论如何,ordered_non_unique索引与std::multimap完全一样,即通过常规的rb-tree,条件是允许具有等效键的元素在容器中共存;没有等效元素或任何东西的列表。至于modify(对于您的特定用例replace更合适),执行以下过程:

  • 检查元素是否到位:O(1)。
  • 如果没有,重新排列:O(log n),其中300,000个元素最多相当于19个元素比较(不是300,000 / 16 = 18,750,如你所说):这些比较按字典顺序在三元组上完成({{1 },attribute1attribute2)。这还不够快吗?嗯,这取决于你的性能要求,所以只有剖析才能真正说明。