【问题标题】:What happens when we use vector erase or insert当我们使用向量擦除或插入时会发生什么
【发布时间】:2017-02-05 13:00:03
【问题描述】:

它是否将所有元素从向量的右侧移动(如果擦除则移动到左侧 1 个位置,如果插入则移动到右侧 1 个位置)还是像链表一样(它创建一个新地址并创建一个新地址。 此外,当我用字符串初始化向量时,它是如何处理内存的。 如果它按顺序存储它,当它达到其最大内存分配时我们继续执行 push_back 会发生什么。

【问题讨论】:

  • 如果您关心速度,请始终进行基准测试,不要陷入旧的“O(N) vs O(1) 所以 O(1) 更快”的陷阱。一般来说,如果您使用 std:: 并且关心速度,那么 vector 几乎总是正确的选择。每个其他容器都会做“坏事”(坏事意味着追逐指针——即使是不应该喜欢无序映射的事情)
  • 您可能想观看 "Modern C++: What You Need to Know - Herb Sutter",从演示开始大约 46 分钟开始:channel9.msdn.com/Events/Build/2014/2-661 Random inserts/deletes using std ::vector 与 std::list 相比,向量在多达 500,00 个元素(大约)时表现更好(也比 std::map 更好)

标签: c++ vector


【解决方案1】:

std::vector 保证(由 C++ 标准)将元素存储在连续的内存区域中。这意味着不,它不像链表,而更像是一个动态分配的数组。当向量达到最大容量后 push_back 元素时,会发生重新分配并将元素复制到新缓冲区中。当您使用插入或擦除元素时也会发生同样的情况,事情会发生变化,因此这些操作通常是 O(N) 而不是 O(1),因为它是链表的情况。

所以看起来std::vectorstd::list 差。情况并非如此,因为在许多应用程序中,读取操作是主要操作,其中 std::vectorstd::list 快得多,因为缓存局部性和 O(1) 随机访问,因为元素是连续存储。 push_back 也是 O(1),除非向量执行重新分配(技术上 push_pack 具有摊销 O(1) 复杂性)。

【讨论】:

  • 谢谢,但是它如何确定它需要为字符串分配多少大小,还是只保留字符串的地址?
  • 由字符串初始化的向量到底是什么意思?通过std::string?如果它是std::string的向量,那么分配器只是为std::string objects分配内存(它们都是固定大小的,即sizeof(std::string),后者负责自己的内存对于它在内部存储的字符串。
  • std::vector<:string>
  • 回复。 “vector 由于缓存局部性而更快”:是的,而且:vector 的随机访问为 O(1),list 的随机访问为 O(N)。
  • @alain 谢谢,确实,修改了答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-31
  • 1970-01-01
  • 1970-01-01
  • 2014-05-25
  • 1970-01-01
相关资源
最近更新 更多