假设我使用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%)开销吗?
答案 0 :(得分:3)
来自this std::unordered_set::reserve
reference
将存储桶的数量设置为容纳至少
count
个元素所需的数量...
还有更多,但要点是std::unordered_set::reserve
实际上不像std::vector::reserve
那样工作。对于无序集,它为哈希表分配存储区,而不是为实际元素本身分配内存。
集合可以每个存储桶中放置一个元素,但不能保证。
答案 1 :(得分:0)
引用标准
将存储桶数设置为至少容纳的数量 在不超过最大负载系数的情况下计算元素并刷新 容器,即考虑到 桶总数已更改
重要的是至少**。我认为您不能依靠该实现,并且请确保它仅使用较少的内存。我的猜测是,无论您是否呼叫reserve
,numElements
的内存使用情况都将相似。