Boost.Multiindex composite_key 密钥存储

Boost.Multiindex composite_key key storage

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

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

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

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

长话短说,我可能会考虑

  • boost::flat_map > 或类似的
  • 使用合适的池分配器提升 struct R { int a,b,c; }(或实际上是同一个元组)的多索引容器。
  • for comparison purposes you could actually use both the flat_map or a vector and use multi-index-container on top of it with T*, T& or reference_wrapper<T> instead of T. I'm not sure what the reduction in storage would be (likely 2 pointer sizes per element?) but at least it lets you measure the index size separately from the storage?

平面地图具有优势,因为它用参考位置换取 iterator/reference 失效。

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

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

请注意,此开销与用于索引的键(提取器)完全无关:composite_key 和 Boost.MultiIndex store/cache 提供的任何其他键提取器均不相关有关密钥的信息。在您的场景中,三个整数数据成员的组合散列在每次需要时即时计算。