为什么std :: vector比std :: deque更受欢迎?

时间:2012-12-07 07:09:21

标签: c++ vector deque

  

可能重复:
  Why would I prefer using vector to deque

我很好奇为什么std::vectorstd::deque更受欢迎。 Deque几乎和查找一样有效,插入更有效(没有vector :: reserve),允许在前面插入/删除。

Herb Sutter曾推荐过if you want to use vector, just prefer deque(我在解读)。然而,在最近关于Writing Modern C++的讨论中,他再次强烈建议将std::vector视为默认容器。根据我之前链接的GOTW,即使标准也有类似的措辞。

这种差异是否有原因?只是vector更简单,更熟知,还是有技术原因?或者是vector只是一个更酷的名字..?

5 个答案:

答案 0 :(得分:56)

我不能为别人说话,但我可以为自己说话。

当我第一次阅读关于std::deque的内容时,我觉得很酷,有一段时间,我不仅把它当作默认容器,而且几乎只用了我使用的 容器

然后有人问起为什么,我详细阐述了它的优点,以及为什么它是几乎所有东西都使用的最佳容器,以及它比std::vector更加通用。

幸运的是,那个质疑我的决定的人很有说服力,我做了一些测试。测试显示,几乎在每种情况下,std::deque都比std::vector慢 - 通常是一个重要因素(例如,大约2)。事实上,在我使用std::deque编写的代码中,只需将std::deque替换为std::vector,除了少数情况外,其他所有代码都会加速。

从那时起,我在少数情况下使用了std::deque,但绝对不再将其视为默认值。简单的事实是,在通常的实现中,对于大多数目的而言,它明显慢于std::vector

但是,我应该补充一点,我有理由相信,通过正确的实现,在几乎所有情况下, 几乎等同于std::vector。大多数人使用从渐近的观点来看无疑是伟大的表现形式,但在现实世界中并没有如此奇妙地(出于许多目的)。

答案 1 :(得分:14)

std::vector非常容易理解,简单且与C兼容(在内存布局和使用指针作为迭代器方面)。

对于某些操作,它也比std::deque更有效。按索引访问元素就是一个例子。

对于给定的任务,使用最简单的容器来完成工作是有意义的。在许多情况下,最简单的容器是std::vector

答案 2 :(得分:5)

std::vector是最常见的容器类外,它还具有优于std::deque的几个优点,即:

  • std::deque的情况不同,典型的std::vector需要额外的间接访问权限。
  • std::deque的情况下的迭代器必须是智能指针,而不是std::vector的指针。
  • std::vector的元素保证是连续的,因此它与以数组作为参数的c风格函数兼容。
  • std::deque不提供任何支持来控制容量和重新分配的时刻。

特别是,最后一点值得注意。

答案 3 :(得分:5)

人们在std :: deque上使用std :: vector的原因很简单。它们与许多C库接口,并且它们具有functions参数,这些参数需要指向连续存储的指针,而std :: deque不能(不能)保证。

另一个原因是当您根据std :: deque构建代码并且您的需求发生变化以便您必须支持连续访问时,您将需要进行一些重构。

我不得不提到有libraries那里的作者声称创建了更有效的矢量实现,以便在capacity增加时克服效率低下。

答案 4 :(得分:5)

std::deque的结构有点复杂,使得天真迭代比std::vector贵得多。插入std::vector及其重新分配往往不是大问题,尤其是在使用reserve()并且仅附加到结尾时。此外,更容易理解std::vector的失效规则,尽管std::deque实际上有一个优势,即只在任一端插入/删除时对象保持不变(请注意std::deque迭代器无效在每次插入时,与插入发生的位置无关)。 std:vector的另一个好处是保证值在内存中是连续的,从而减少内存分配。

我想,我建议使用std::deque算法进行一致优化以使用分段序列(我不知道任何标准C ++库进行此优化)并且用户使用算法一致地访问序列(目前为止)据我所知,只有一小部分用户考虑使用算法的选项。否则,我怀疑只有当你利用它的特定属性时std::deque才是性能方面更好的选择(例如,对象保持不变并且你可以在最后插入/删除)。不过,值得描述两种选择。