【问题标题】:std::unordered_map<> bucket_count() after default rehash默认重新散列后的 std::unordered_map<> bucket_count()
【发布时间】:2020-06-15 14:19:59
【问题描述】:

如果我不断向 unordered_map 添加值,那么每次元素数量超过 bucket_count()(假设 max_load_factor = 1)时,都会发生重新散列。

我很困惑的是重新散列后的桶大小。

#include <iostream>
#include <unordered_map>
int main() {
   std::unordered_map<size_t, size_t> mp;

   for (size_t i = 0; i < 1000; ++i) {
      mp[i] = i;
      std::cout << " count: " << mp.bucket_count() << std::endl;
   }
}

这输出 3 7 17 37 79 167 337 709 1493

我注意到存储桶大小是素数,大约翻了一番。然而,它也不是最接近 2 的下一个幂的素数。

增加存储桶大小的方法是什么。 我很惊讶或很愚蠢,以至于在 cplusplus.com 等标准参考资料中找不到任何关于它的信息

【问题讨论】:

  • 它很可能是实现定义的。我相信 g++ 和 clang 使用的实现是开源的。
  • 标准没有任何要求。也许素数的使用使得哈希算法可以保证哈希中的高度不同的位模式,只需要稍微不同的对象。
  • @ÖöTiib:这非常令人惊讶。众所周知,这些映射具有恒定时间插入。如果标准只要求插入也可以在每次插入后触发重新散列,即使其成为线性时间操作。
  • @FloRyan 如果您担心,请保留()。以我的经验,不同实现的 std::unordered_maps 在性能上相对相似。更大的惊喜可能是 std::deque ,它的块大小在实现之间确实不同,性能可能会明显不同,但没有办法调节块的大小,也没有办法保留()。

标签: c++ std unordered-map


【解决方案1】:

重新散列后的存储桶大小将取决于编译器。您看到的具体数字可以通过获取当前存储桶大小乘以 2,然后从此处的 __prime_list 数组中获取大于该值的最接近的素数来找到:https://github.com/gcc-mirror/gcc/blob/5bea0e90e58d971cf3e67f784a116d81a20b927a/libstdc%2B%2B-v3/src/shared/hashtable-aux.cc

【讨论】:

    猜你喜欢
    • 2019-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-23
    • 1970-01-01
    • 2017-07-18
    • 2014-08-21
    • 2014-10-04
    相关资源
    最近更新 更多