【问题标题】:Vector vs Deque insertion in middle中间插入向量与双端队列
【发布时间】:2012-09-07 17:55:32
【问题描述】:

我知道 deque 在插入位于前端或末尾时比 vector 更有效,如果我们必须进行指针运算,则 vector 更好。但是当我们必须在中间执行插入时使用哪一个。?为什么。?

【问题讨论】:

  • 双端队列的效率可能不会更高,尤其是在元素数量很少的情况下。
  • 对于相对较小的廉价复制对象集合,vector 胜过其他容器,无论操作如何。 (我测量了 vector<char> 与 deque<char> 的最大 12 个字符的 FIFO,虽然 deque 针对这种利用率进行了优化,vector 在我测试的机器上明显更快。)
  • 只是一个细微差别:我觉得奇怪的是,双端队列允许在中间进行排队操作......队列的最严格实现只允许插入到后面并在后面移除前面。

标签: c++ stl vector deque


【解决方案1】:

std::deque 可以在大型容器中表现更好,因为它通常实现为连续数据块的链接序列,而不是 std::vector 中使用的单个块。因此,中间的插入将导致更少的数据从一个地方复制到另一个地方,并可能减少重新分配。

当然,这是否重要取决于容器的大小和复制所存储元素的成本。使用 C++11 移动语义,后者的成本不太重要。但归根结底,了解的唯一方法是使用实​​际应用程序进行分析。

【讨论】:

  • 我同意,但需要注意的是,第 1 段中的连续数据块是逻辑的,而不是物理的。 OP 应该更多地研究物理布局,以充分了解中间插入的后果
  • 正如我在对 Doug T. 的回答的评论中指出的那样,这是错误的。如果您在接近开头的位置插入,deque可以选择仅移动插入之前的元素,因此移动小于vector。我不知道是否有任何实现实际上这样做了,无论如何,它必须在插入的一侧移动 all 元素,无论是之前还是之后。
  • @JamesKanze 也许我的回答很糟糕。我对你说的没有异议。我的观点是,对于“双端队列”,要移动的所有元素比对于“向量”的数字更小。
【解决方案2】:

您可能认为deque 具有优势,因为它将数据分成块存储。然而,在恒定时间内实现operator[] 需要所有这些块的大小相同。在中间插入或删除元素仍然需要移动一侧或另一侧的所有值,与vector 相同。由于vector 更简单并且具有更好的缓存局部性,因此它应该领先。

【讨论】:

    【解决方案3】:

    标准库容器的选择标准是,您选择容器取决于:

    1. 您要存储的数据类型 &
    2. 您要对数据执行的操作类型。

    如果您想在中间执行大量插入,最好使用std::list。

    如果只是在std::deque 和std::vector 之间进行选择,那么需要考虑许多因素:

    • 通常,在 deque 访问元素的情况下还有一种间接方式,因此 element 双端队列的访问和迭代器移动通常会慢一些。
    • 在对内存块有大小限制的系统中,双端队列可能包含更多元素,因为它使用了多个内存块。因此,max_size() 对于双端队列可能更大。
    • 双端队列不支持控制容量和重新分配的时刻。在 特别是除开头或结尾之外的任何元素的插入或删除 使引用双端队列元素的所有指针、引用和迭代器无效。 但是,重新分配可能比向量执行得更好,因为根据它们的 典型的内部结构,双端队列不必在重新分配时复制所有元素。
    • 内存块在不再使用时可能会被释放,因此 双端队列可能会缩小(这不是标准强加的条件,但大多数实现都会这样做)

    【讨论】:

    • 这并不像看起来那么明显。在现代架构上,std::list 的效率非常低,一般来说,因为它的局部性很差,如果内容复制起来很便宜,尽管复制,插入到vector 的中间会更快。跨度>
    • 另外,deque 的内部结构确实要求它复制插入至少一侧的所有元素,如果插入不在末尾。 (更一般地说,vector 需要在插入之后移动所有元素,deque 需要移动之后的所有元素或之前的所有元素。)
    【解决方案4】:

    双端队列仍然会更有效率,因为它不必在每次插入元素时移动数组的一半。

    当然,这只有在您考虑大量元素时才真正重要,甚至建议您运行基准测试并查看哪个在您的特定情况下效果更好。请记住premature optimization is the root of all evil。

    【讨论】:

    • 除非您在一端插入,否则deque 将需要移动一些元素:要么全部在插入之前,要么全部在插入之后。
    • @JamesKanze 是的,但通常只有有限的数量需要移动。我很确定它不会像向量那样是所有元素的一半。
    猜你喜欢
    • 1970-01-01
    • 2015-05-01
    • 2018-05-18
    • 1970-01-01
    • 2017-05-06
    • 2012-03-27
    • 1970-01-01
    • 2013-05-21
    • 1970-01-01
    相关资源
    最近更新 更多