C ++向量和列表插入

时间:2013-04-25 01:51:43

标签: c++ performance list vector

有人知道为什么在列表中间插入一个元素会更快 而不是将一个元素插入向量的中间?

我更喜欢使用矢量,但如果可以,我会被告知使用列表。 任何人都能解释为什么? 是否始终建议在列表上使用列表?

4 个答案:

答案 0 :(得分:8)

如果我逐字逐句地提出问题,找到数组的中间(std :: vector)是一个简单的操作,你将长度除以2,然后向上或向下舍入以得到索引。找到双向链表(std :: list)的中间部分需要遍历所有元素。即使你知道它的大小,你仍然需要走过一半的元素。因此std :: vector比std :: list快,换句话说,一个是O(1),而另一个是O(n)。

在已知位置插入需要对数组的相邻元素进行混淆,只需在另一个节点中链接以获得双向链表,正如其他人在此处所解释的那样。因此,带有O(1)的std :: list比带有O(n)的std :: vector快。

在正确的中间插入,我们有数组的O(1)+ O(n)和双链表的O(n)+ O(1),插入中间O(n) )对于两种容器类型。所有这些都省去了CPU缓存和分配器速度之类的事情,它只是比较了“简单”操作的数量。总之,您需要了解如何使用容器。如果你真的在随机位置插入/删除很多,std :: list可能会更好。如果你很少这样做,然后只读取容器,std :: vector可能会更好。如果你只有十个元素,那么所有的O(x)都可能毫无价值,你应该选择你最喜欢的那个。

答案 1 :(得分:1)

插入向量的中间需要将插入点之后的所有元素混合起来以留出空间,这可能涉及大量复制。

该列表实现为链表,每个节点在内存中占用自己的空间,并引用相邻节点,因此添加新节点只需要更改2个引用即可指向新节点。

根据您使用的数据类型,矢量的执行速度可能比列表快得多。但是复制对象越复杂,矢量就越差。

答案 2 :(得分:0)

简单来说,vector是一个数组。因此,其元素存储在连续的存储位置(即,一个接着另一个)。唯一的例外是矢量允许在运行时调整大小,而不会导致数据丢失。

现在,要插入列表,您需要标识节点,然后创建新元素(内存中的任何位置),存储值并连接指针。

但是对于vector(数组),您必须将元素从一个单元格物理移动到另一个单元格,以便为新元素创建该空间。该物理运动是导致延迟的原因,特别是在需要移动许多元素(即数据)的情况下。你不是在物理上移动数组元素。相反,它的内容。

答案 3 :(得分:0)

Ulrich Eckhardt的回答非常好。我没有足够的声誉来添加评论,所以我会自己写一个答案。像Ulrich说的那样,列表和向量的中间插入速度在理论上是O(n)。在实践中,现代CPU有一种称为“预取器”的东西。它非常适合获取连续的数据。由于向量在内存中是连续的,因为预取器会移动很多元素。你需要操作真正的,非常大的向量,以使它们在插入时比列表慢。有关详细信息,请查看此精彩博文:

http://gameprogrammingpatterns.com/data-locality.html