std::unordered_set::保留容器内存要求的角色?

Role of std::unordered_set::reserve for container memory requirement?

本文关键字:角色 内存 unordered set 保留 std      更新时间:2023-10-16

假设我使用std::unordered_set<MyClass>,并假设sizeof(MyClass)很大,即比sizeof(size_t)sizeof(void*)大得多。我将向无序集合添加大量numberOfElementsToBeAdded元素。

从 https://stackoverflow.com/a/25438497/4237,我发现: "每个内存分配可以四舍五入到便于内存分配库管理的大小 - 例如,下一个 2 的幂,接近 100% 的最坏情况低效和 50% 的平均值,所以让我们添加 50%,仅用于列表节点,因为存储桶可能是给定size_t和指针的 2 的幂:50% * size() * (sizeof(void*) + sizeof((M::value_type))">

这促使我得出结论,实际内存消耗将在1*numberOfElements*sizeof(MyClass)(1+1)*numberOfElements*sizeof(MyClass)模化一些额外的内存,这在这里没什么兴趣,因为它是sizeof(size_t)的。

但是,我知道要提前添加的元素数量,所以我打电话:

std::unordered_set<MyClass> set;
set.reserve(numberOfElementsToBeAdded);
//Insert elements

考虑到调用 std::vector::reserve 的并行,我猜这避免了潜在的开销,从而保证内存消耗大约是1*numberOfElements*sizeof(MyClass)(模化一些额外的内存,再次是sizeof(size_t)级)。

我可以依靠标准库的实现来保证像这样的调用reserve将避免上述答案中提到的 0-100%(平均 50%)开销吗?

来自此std::unordered_set::reserve参考

将存储桶数设置为容纳至少count个元素所需的数量...

还有更多,但要点是std::unordered_set::reserve实际上并不像std::vector::reserve那样工作。对于无序集合,它为哈希表分配存储桶,而不是为实际元素本身分配内存。

该集合可以为每个存储桶放置一个元素,但不能保证。

引用标准:

将存储桶数设置为至少容纳存储桶所需的数量 在不超过最大负载系数的情况下对元素进行计数,并重新散列 容器,即将元素放入适当的存储桶中,考虑 存储桶总数已更改

重要的部分是**至少*。我认为您不能依赖该实现并确保它仅使用较少的内存量。我的猜测是,无论您是否调用reservenumElements的内存使用情况都将相似。