假设我使用std::unordered_set<MyClass>
,并假设sizeof(MyClass)
很大,即比sizeof(size_t)
和sizeof(void*)
大得多。我将在无序集中添加大量numberOfElementsToBeAdded
元素。
从https://stackoverflow.com/a/25438497/4237,我发现:“每个内存分配可以四舍五入到便于内存分配库管理的大小 - 例如,下一个2的幂,接近100%最坏情况下的低效率和50%的平均值,所以让我们增加50%,仅用于列表节点,因为桶可能是两个给定size_t和指针的幂: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%)开销?
来自this std::unordered_set::reserve
reference
将桶数设置为至少容纳
count
元素所需的数量...
还有更多,但要点是std::unordered_set::reserve
实际上不像std::vector::reserve
那样工作。对于无序集,它为哈希表分配存储区,而不为实际元素本身分配存储区。
该套装可以为每个桶装一个元素,但不能保证。
引用标准:
将桶的数量设置为容纳至少count个元素而不超过最大负载因子所需的数量,并重新对容器进行重新设置,即考虑到桶的总数已更改,将元素放入适当的桶中
重要的部分是**至少*。我不认为你可以依赖于实现,并确保它只使用较少的内存。我的猜测是,无论你打电话给reserve
,numElements
的内存使用情况都是类似的。