【问题标题】:Choosing List or Vector for a given scenario in C++在 C++ 中为给定场景选择列表或向量
【发布时间】:2013-11-16 10:24:27
【问题描述】:

对于我的应用程序,我使用的是 STD 向量。我在最后插入向量,但是从向量中随机擦除,即元素可以从中间、前面的任何地方擦除。这两个只是要求,1)在末尾插入 2)从任何地方擦除。

所以我应该使用 STD 列表,因为擦除确实会移动数据。或者我会出于任何原因在我的代码中保留 Vector??

请发表评论,如果 Vector 是更好的选择,这里的 List 会更好吗?

【问题讨论】:

  • IMO,如果删除元素是代码的一个重要方面,那么选择 std::list;如果您不经常删除元素或者如果向量很小,请保留该向量。
  • 有人会说使用std::vector,句号。在性能方面,缓存局部性往往比插入或删除的复杂性更重要。 youtube.com/watch?v=YQs6IC-vgmo
  • @MarcClaesen 我几个月来一直在 stackoverflow 上发布 Bjarn 视频,没有人会盲目注意。 “我们知道列表更好,拉拉拉......”如果你把你的评论作为答案,我会投票给它。
  • @user1158692 把它变成了答案:)

标签: c++


【解决方案1】:

使用std::vector 而不是std::list 的一个关键原因是cache locality。在这方面,列表很糟糕,因为它的元素在你的记忆中可能(而且通常是)碎片化的。这会显着降低性能。

有些人会建议几乎总是使用std::vector。在性能方面,缓存局部性往往比插入或删除的复杂性更重要。

Here's a video about Bjarne Stroustrup's opinion regarding subject.

【讨论】:

    【解决方案2】:

    我会向您推荐这份备忘单,结论就是清单。

    【讨论】:

    • 你自己画的还是从网上抄来的?在第二种情况下,你会做一个链接吗?
    • 我在stackoverflow上看到了这张图片,很抱歉,但我不知道它的原始引用。编辑:显然它来自freenode.net,但我没有原始链接。
    【解决方案3】:

    列表支持在恒定时间内在任意但已知位置删除。

    查找该位置需要线性时间,就像修改向量一样。

    列表的唯一优点是,如果您在(大约)相同的位置重复擦除(或插入)。

    如果您或多或少地随机擦除,则向量的更好的内存局部性最终可能会胜出。

    唯一确定的方法是衡量和比较。

    【讨论】:

      【解决方案4】:

      在这种情况下,列表很可能更好。 list 优于 vector 的优点是它支持在任意位置以恒定复杂度进行删除。 vector 只有在需要对容器元素进行恒定索引操作时才是更好的选择。您仍然必须考虑如何将要删除的元素传递给您的函数进行删除。如果你只传递一个索引,vector 将能够在恒定时间内找到元素,而在 list 中你将不得不迭代。在这种情况下,我将对这两种解决方案进行基准测试,但我仍然会打赌列表表现更好。

      【讨论】:

      • 我从下面的stackoverflow链接中读到,遍历列表会导致缓存未命中,尽管我并不完全理解。如果我使用列表,它会花费我吗?请解释!!链接的第五个答案:stackoverflow.com/questions/238008/…
      • 除非你测量它,否则你不能肯定地说。另外,你必须找到中间的元素,向量是O(1),列表是O(N)。
      • @juanchopanza 我同意我最初的陈述有点强烈。我重新措辞了一下我的答案。
      • 那好多了,+1。
      【解决方案5】:

      这取决于许多因素以及您如何使用您的数据。

      一个因素:您是否需要一个保持集合顺序的擦除?或者你可以忍受不断变化的订单?

      其他因素:集合中有哪些类型的数据? (数字:整数/浮点数)||指针 ||对象

      不遵守秩序

      如果数据是基本数字或指针,您可以继续使用vector,要删除一个元素,您可以将向量的最后一个元素复制到删除的位置,然后pop_back()。这样可以避免移动所有数据。

      如果使用对象,如果你需要复制的对象很小,你仍然可以使用相同的方法。

      维持秩序

      也许 List 会是你的朋友,不过,还是会建议进行一些测试,具体取决于数据的大小、列表的大小等

      【讨论】:

      • 我不关心订单,数据是指针。谢谢你的建议。复制最后一个元素和 pop_back 将解决我的问题。
      • @Chris 好吧,如果它解决了你的问题,也许你可以接受答案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多