[英]Pre-allocating buckets in a C++ std::unordered_map
我正在使用来自gnu ++ 0x的std::unordered_map
来存储大量数据。 我想为大量元素预分配空间,因为我可以绑定使用的总空间。
我想做的是致电:
std::unordered_map m;
m.resize(pow(2,x));
x是已知的。
std::unordered_map
不支持此功能。 如果可能的话,我宁愿使用std::unordered_map
,因为它最终将成为标准的一部分。
其他一些限制:
需要可靠的O(1)访问和地图突变。 所需的哈希和比较功能已经是非标准的,并且有些昂贵。 O(log n)突变(与std::map
)太昂贵了。
->昂贵的哈希和比较也使基于摊销的增长方式过于昂贵。 每个额外的插入都需要这些函数进行O(n)个操作,这会导致算法的运行时间增加一个二次项,因为指数存储需求需要O(n)增长。
m.rehash(pow(2,x));
如果pow(2, x)
是您要预分配的存储桶数。 你也可以:
m.reserve(pow(2,x));
但是现在pow(2, x)
是您计划插入的元素数。 这两个函数除了预分配存储桶外什么都不做。 他们不插入任何元素。 它们都打算完全用于您的用例。
注意:不保证您会获得确切的pow(2, x)
桶。 一些实现将仅使用数量为2的幂的存储桶,其他实现将仅使用素数的存储桶。 还有一些将仅使用质数的子集作为存储桶的数量。 但是无论如何,实现应接受您所希望的存储桶数量的提示 ,然后在内部向上舍入到下一个可接受的存储桶数量。
这是最新(N4660)用于指定rehash
参数的精确措辞:
a.rehash(n)
: 后置条件: a.bucket_count() >= a.size() / a.max_load_factor() and a.bucket_count() >= n
。
load_factor()
置条件确保bucket()_count() >= n
,并且load_factor()
保持小于或等于max_load_factor()
。
随后,根据rehash(n)
定义了reserve(n)
rehash(n)
:
a.reserve(n)
:与a.rehash(ceil(n / a.max_load_factor()))
。
我认为无序映射具有预先分配的内存并不重要。 STL预期为O(n)摊销的插入时间。 在我看来,要省去编写自己的分配器的麻烦,直到您知道这是代码的瓶颈。
我建议为std::unordered_map
编写自己的分配器,该分配器完全按照您想要的方式分配内存。
构造函数根据http://en.cppreference.com/w/cpp/container/unordered_map/unordered_map采用参数“ size_type bucket_count”
因此,执行示例代码所说的最简单的方法是:
std::unordered_map m{ pow(2,x) };
这将更加有效,因为它不确定在构造上将保留多少个存储桶,否则,当您随后调用reserve时,它可能必须先分配然后再分配。
我认为,仅在事先知道映射值将占用多少内存的情况下,重新哈希和保留两者才能起作用。 如果映射值很复杂或大小动态变化(例如,向量),则需要自己的实现。 例如,如果您的内存大小允许,则可以保留可能碰巧存在的最大容器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.