std :: vector与std :: list与std :: slist的相对表现?

时间:2008-10-26 13:24:34

标签: c++ data-structures stl performance linked-list

对于不需要随机访问列表元素的简单链接列表,使用std::list而不是std::vector是否有任何明显的优势(性能或其他方面)?如果需要向后遍历,那么在迭代其元素之前使用std::slistreverse()列表会更有效吗?

7 个答案:

答案 0 :(得分:56)

通常情况下,性能问题的最佳答案是profile针对您的用例的两种实现,并查看哪种更快。

一般情况下,如果您在数据结构中插入(除了最后),那么vector可能会更慢,否则在大多数情况下vector的效果要好于list如果仅用于data locality issues,这意味着如果数据集中相邻的两个元素在内存中相邻,那么下一个元素将已经位于处理器的缓存中,并且不必将内存页面错误归入高速缓存中。

还要记住,vector的空间开销是常量(3个指针),而list的空间开销是为每个元素支付的,这也减少了完整元素的数量(数据加上开销),任何时候都可以驻留在缓存中。

答案 1 :(得分:26)

在C ++中想到的默认数据结构是 Vector

考虑以下几点......

1]遍历:
列表节点分散在内存中,因此列表遍历会导致 缓存未命中 。但是向量的遍历是平滑的。

2]插入和删除:
当您对Vector执行此操作时,必须移动平均50%的元素,但缓存非常擅长!但是,对于列表,您需要 遍历到插入/删除点...... 所以再次......缓存未命中! 令人惊讶的是,矢量也赢得了这个案例!

3]存储:
使用列表时,每个元素有2个指针(前向和后向),因此List比Vector大得多! 向量只需要比实际元素需要更多的内存。

Yout应该有理由不使用矢量。

<小时/> 参考:
我在主Bjarne Stroustrup的演讲中学到了这一点:https://youtu.be/0iWb_qi2-uI?t=2680

答案 2 :(得分:12)

根本没有。列表优于Vector,但顺序访问不是其中之一 - 如果这就是你所做的一切,那么矢量就更好了。

然而..添加额外元素比列表更昂贵,特别是如果你插入中间。

了解这些集合是如何实现的:向量是一个连续的数据数组,列表是一个包含数据和指向下一个元素的指针的元素。一旦你理解了这一点,你就会明白为什么列表对插入有好处,对随机访问有害。

(因此,向量的反向迭代与正向迭代完全相同 - 迭代器每次只减去数据项的大小,列表仍然必须通过指针跳转到下一个项目)

答案 3 :(得分:4)

如果您需要向后遍历,则滑板不太可能是您的数据结构。

传统(双重)链接列表为您提供列表中任何位置的恒定插入和删除时间;向量仅在列表末尾给出分摊的常量时间插入和删除。对于向量插入和删除时间,除了结束之外的任何地方都是线性的。这不是全部故事;也有不变因素。向量是一种更简单的数据结构,根据上下文有优点和缺点。

了解这一点的最佳方法是了解它们的实施方式。链表具有每个元素的下一个和前一个指针。向量具有索引所寻址的元素数组。从中可以看出,两者都可以进行有效的前向和后向遍历,而只有一个向量可以提供有效的随机访问。您还可以看到链表的内存开销是每个元素,而向量是常量。您还可以看到为什么两个结构之间的插入时间不同。

答案 4 :(得分:4)

有关该主题的一些严格基准: http://baptiste-wicht.com/posts/2012/12/cpp-benchmark-vector-list-deque.html

正如其他人所指出的,连续的内存存储意味着std :: vector对于大多数事情来说更好。几乎没有充分的理由使用std :: list,除了少量数据(它可以全部适合缓存)和/或频繁擦除和重新插入的地方。 复杂性保证与实际性能无关,因为缓存和主内存速度之间的差异(200x)以及连续的内存访问如何影响缓存使用。请参阅Chandler Carruth(谷歌)在此讨论此问题: https://www.youtube.com/watch?v=fHNmRkzxHWs

Mike Acton的数据导向设计在这里讲述: https://www.youtube.com/watch?v=rX0ItVEVjHc

答案 5 :(得分:2)

有关费用的详细信息,请参阅此问题:
What are the complexity Guarantees of the standard containers

如果你有一个slist,你现在想以相反的顺序遍历它,为什么不改变类型到任何地方列出?

答案 6 :(得分:0)

  • std::vector 在查找元素方面比 std::list 快得多
  • std::vector 在处理非常小的数据时总是比 std::list 执行得更快
  • std::vector 总是比 std::list 更快地将元素推到后面
  • std::list 可以很好地处理大元素,特别是对于 在前面排序或插入

注意:如果您想了解有关性能的更多信息,我建议您查看this