【问题标题】:What is the raw_storage_iterator component uses/advantages in C++什么是 raw_storage_iterator 组件在 C++ 中的用途/优点
【发布时间】:2014-04-10 01:11:49
【问题描述】:

我正在阅读关于 raw_storage_iterator 组件的 TC++PL。使用这个组件,我们获得了性能优势,因为它避免了分配(更昂贵)并使用复制构造。在我看来,它应该用在序列/容器中,我们可以有大量元素,因此分配调用的数量可能会产生很大的影响。

理论上它很清楚,在我看来这个组件对容器类型类很有用。但是我想了解我们应该在哪里使用这个组件(带有实际示例)来获得它的性能优势?

【问题讨论】:

  • inb4 "cplusplus.com 很烂,你不敢链接到它";它在那里说,它已被使用,因此您可以使用未初始化的内存作为算法的目标。性能应该不会比带有后插入迭代器的保留向量好。除非你正在编写非常底层的代码,否则你不需要这个迭代器。
  • @DanielKO 带有后插入迭代器的保留向量必须在每次插入时进行大小检查。编译器找出不需要大小检查的可能性相对较小。您将在检查中获得良好的分支预测,但仍会小于raw_storage_iterator 写作。
  • 顺便说一下,它在 C++17 中已被弃用,并在 C++20 中被删除。所以建议不要使用。

标签: c++ performance c++11 copy-constructor assignment-operator


【解决方案1】:

cppreference 有示例代码。

您可以通过多种机制分配对齐的未初始化内存块。 Cppreferences 使用std::get_temporary_buffer<T> 来分配这样一个缓冲区。

然后您可以创建指向这些元素的指针。指针的类型有点误导,因为它不是指向有效 T 的指针,而是指向适合构造T 的内存块。

std::raw_storage_iterator 可以用 T* 填充并告诉它输出。然后,您可以将该迭代器提供给期望传统输出迭代器的算法,一切顺利。

如果您尝试在没有raw_storage_iterator 的情况下执行此操作,您将分配给非构造的T,这是未定义的行为。作为替代方案,您可以在输出到 T 之前构造它们——但这很浪费,因为它构造了两次对象。

基本思想是允许在标准算法中以近乎完美的效率使用未初始化的输出缓冲区。除了一些严肃的代码微优化之外,您不应该使用它。

【讨论】:

  • 那么这不是使用placement new 的好地方吗?这将使构造的对象立即进入保留空间。这仍然需要程序员获得足够的空间,但看起来它可能会更好的性能和安全性。
  • @paul 这个迭代器确实使用了位置new,只是在分配给它时它会这样做。原始存储迭代器允许您将此作为来自std 的某些算法的输出——其中一些您可能不想手动滚动。
猜你喜欢
  • 2020-02-07
  • 1970-01-01
  • 2019-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多