为什么std :: vector比std :: deque更受欢迎?
可能重复:
为什么我更喜欢使用vector来检测
我很好奇为什么std::vector
比std::deque
更受欢迎。 Deque在查找方面几乎同样高效,插入效率更高(没有vector :: reserve),并允许在前面插入/删除。
香草萨特曾经build议, 如果你想使用vector,只喜欢德克 (我是释义)。 然而,在最近的写作现代C + +的谈话,他再次强烈build议思考作为默认容器的std::vector
。 根据前面联系的GOTW ,甚至标准也有类似的措辞。
这种差距有什么原因吗? 这只是vector
更简单,更知名,还是有技术上的原因? 或者是vector
只是一个更酷的名字..?
我不能为别人说话,但我可以为我自己。
当我第一次读到std::deque
,我觉得它足够酷了一段时间,我不仅把它当作默认的容器,而且几乎是我使用的唯一的容器。
然后有人问到为什么,我详细阐述了它的优点,以及为什么它是几乎所有东西中使用的最好的容器,以及它如何比std::vector
多得多。
幸运的是,那个质疑我的决定的人很有说服力,我做了一些testing。 testing表明,几乎在所有情况下, std::deque
都比std::vector
慢 – 通常是一个相当大的因素(例如2)。 事实上,在我使用std::deque
编写的代码中,只需将std::deque
replace为std::vector
就可以在除less数情况之外的所有情况下加速。
在这之后的几个例子中,我使用了std::deque
,但是绝对不要把它作为默认值。 简单的事实是,在大多数情况下,在通常的实现中,它明显比std::vector
慢。
但是,我应该补充一点,我相当肯定的是,通过正确的实现,在几乎所有情况下,它几乎都可以和std::vector
相当。 大多数情况下,从一个渐近的观点来看,这个表示无疑是非常好的,但是在现实世界中却不是如此奇妙(对于很多目的而言)。
std::vector
非常好理解,简单并且与C兼容(无论是在内存布局方面,还是在使用指针作为迭代器方面)。
对于一些操作,它也比std::deque
更高效。 通过索引访问元素就是一个例子。
对于一个给定的任务,使用最简单的容器来完成工作是很有意义的。 在很多情况下,最简单的容器是std::vector
。
由于一个简单的原因,人们在std :: deque上使用std :: vector。 它们与很多C库接口,它们具有需要指向连续存储的参数的函数 ,而std :: deque不能(不能)保证。
另一个原因是当你根据std :: deque构build代码,并且你的需求改变了,所以你必须支持连续的访问,你将会有一些重构。
我不得不提到,有些图书馆的作者声称创build了更高效的vector实现,以便在容量增加时克服效率低下的问题。
std::deque
的结构稍微复杂一些,这使得天真的迭代比std::vector
要贵一些。 插入std::vector
与重新分配往往不是大问题,特别是使用reserve()
和只附加到结束。 此外,更容易理解std::vector
无效规则,尽pipe它实际上是std::deque
一个优点,即当只在两端插入/删除时,对象仍然保持放置状态(注意std::deque
迭代器在每次插入时都会失效,独立于插入发生的地方)。 std:vector
另一个std:vector
是可以保证这些值在内存中是连续的,从而减less了内存分配。
我想,我会build议使用std::deque
algorithm一直优化使用分段序列(我不知道任何标准的C ++库做这种优化)和用户访问序列一致使用algorithm(据我可以告诉,只有极less数用户认为使用algorithm的选项)。 否则,我会怀疑std::deque
只有在利用其特定属性(例如,对象保持放置并且可以在最后插入/删除)的情况下才是性能方面更好的select。 尽pipe如此,还是值得介绍两种方法。
除了std::vector
是最常见的容器类之外,它还比std::deque
有几个优点,即:
- 一个典型的
std::deque
需要一个额外的间接访问elments不像std::vector
。 - 在
std::deque
情况下,迭代器必须是智能指针,而不是指向std::vector
指针。 -
std::vector
元素保证是连续的,因此它与以数组为参数的c样式函数兼容。 -
std::deque
不支持控制容量和重新分配的时刻。
特别是最后一点值得注意。