为什么 std::d eque 不允许指定存储桶大小?
Why doesn't std::deque allow specifying the bucket size?
std::deque
将元素存储在固定大小的"桶"(数组)中。不同的编译器使用不同的存储桶大小:
- MSVC:16 字节或元素大小(如果更大)
- GCC:512 字节或元素大小(如果更大) 叮
- 叮当当:
element_size < 256 ? 4096 : element_size * 16
对于 MSVC(尤其是)和 GCC,如果 deque 元素大小大于硬编码大小,std::deque
在大多数情况下会变成一个复杂的std::list
,性能会降低。
在我看来,Clang 做得更好,无论 deque 元素的大小如何,桶至少会有 16 个元素。尽管在某些情况下,对于小型元素,4096 字节的最小存储桶大小可能不是最佳的。
为什么std::deque
没有一个额外的模板参数来表示存储桶大小,其默认值为供应商认为合理的默认值?这不会破坏向后兼容性,但可以优化性能。
deque
就像一个黑匣子。 没有指定它是如何实现的。 该实现可以自由使用任何它喜欢的技术来符合性能要求。 因此,它不能将存储桶大小作为模板参数。
当然,这样的数据结构是有用的。 标准可以选择提供它(以deque
名称或作为新容器),但他们没有。 相比之下,unordered_*
容器保证使用存储桶。 Per [unord.req]/9:
无序关联容器的元素被组织成桶。具有相同哈希代码的密钥将显示在同一存储桶中。当元素添加到 一个无序的关联容器,使得平均数量 每个存储桶的元素保持在边界以下。重新散列使无效 迭代器,更改元素之间的顺序,以及更改 存储桶元素出现在 中,但不会使指针或 对元素的引用。对于
unordered_multiset
和unordered_multimap
,重新散列保留了 等效元素。
deque
没有类似的措辞。
相关文章:
- std::原子加载和存储都需要吗
- 如何从存储在std::映射中的std::集中删除元素
- 使用 pqxx 将 std::vector 存储在 postgresql 中,并从数据库中检索它
- 在std::vector上存储带有模板的类实例
- 在 std::无符号字符的向量处存储 int 的十六进制表示形式
- 将无符号字符的向量存储在数组中会给我 std::bad_alloc
- 如何调用存储在指向"std::函数"的指针中的 lambda?
- 如何访问存储在 std::variant 中的类的方法
- std::vector move 而不是交换到空 vector 并释放存储
- 将可变参数模板类存储到 std::vector 中
- 在 std::vector<无符号字符中存储任意数据的方法>
- 存储 std::list 元素的地址;内存
- 在 C++11 智能指针中存储 std::thread
- 存储 std::p romise<R&>:"通信对象"
- 如果类型需要模板,如何存储std ::向量
- 在“std::map”中插入一个“int”值,该值应该存储“std::string”
- 这是存储 std::分配器状态的正确方法 - 在这种情况下,由 Windows 上的共享内存支持
- 为什么 libstdc++ 以相反的顺序存储 std::tuple 元素
- 模板化存储std::vector中的多种不同类型
- 存储 std::shared_ptr 的向量,<Foo>其中 Foo 是一个模板化类