Boost.Multiindex Composite_key 密钥存储

问题描述

假设我为 boost::multi_index_container 形成了一个由三个整数成员组成的复合键。键将涵盖某个范围内三个整数的每个组合({0,0},{0,1},2} 等)。在内部,boost 是否将这些整数组合中的每一个存储为一个键,以便键的总数为 N x N x N,其中 N 是范围内元素的数量,而散列键可能是数字的 3 倍字节数。或者,它是否试图通过在内部使用例如可以减少总索引字节大小的哈希表树来节省内存?

我想弄清楚自己创建哈希表树是否会减少整体索引字节大小。

解决方法

散列索引的大小/开销是每个元素 2+1/LF 个指针,其中 LF 是索引加载因子。 LF 通常介于 MLF/2 和 MLF 之间,其中 MLF 是允许的最大负载因子,默认为 1 ,因此开销介于每个元素 2+2=4 和 2+1=3 个指针之间,即平均每个元素 3.5 个指针。

请注意,此开销与用于索引的键(提取器)完全无关:composite_key 或 Boost.MultiIndex 提供的任何其他键提取器都不会存储/缓存有关键的任何类型的信息。在您的场景中,来自三个整数数据成员的组合散列在每次需要时即时计算。

,

会产生什么样的索引表示取决于索引的类型。对于 hashed_unique/unordered_unique,您可以假设底层索引被组织为一棵树。

但是,主存储不一定是最佳的。所有 Muiti-Index 容器都是基于节点的,这意味着不能保证元素在内存中是连续的(但在删除之前始终具有引用/迭代器稳定性)。这并不意味着必须始终单独分配所有节点:这可以由库优化,也可以通过使用自定义分配器来影响。

长话短说,我可能会考虑

  • boost::flat_map > 或类似的
  • 使用合适的池分配器提升 struct R { int a,b,c; }(或实际上相同的元组)的多索引容器。
  • 出于比较目的,您实际上可以同时使用 flat_map 或向量,并在其顶部使用带有 T*T&reference_wrapper<T> 的多索引容器,而不是T。我不确定存储的减少会是多少(每个元素可能有 2 个指针大小?)但至少它可以让您与存储分开测量索引大小?

平面映射具有优势,因为它将引用的局部性用于迭代器/引用失效。

要测量您的实际内存占用量,请使用堆分析器(例如 valgrind --tool=massif)。