【问题标题】:vector vs list insert performance [closed]矢量与列表插入性能[关闭]
【发布时间】:2014-05-18 05:11:59
【问题描述】:

我刚刚观看了 Herb Sutter 关于各种 STL 容器性能的演示(请参阅 http://channel9.msdn.com/Events/Build/2014/2-661 上的第 46 分钟)。看起来std::vectorstd::list 更快,即使是在中间插入,这看起来像是一个很大的NO-NO 首先......他的解释是这是因为std::vector 中的连续内存分配而发生的,并且因为线性横向似乎超级快。我现在很好奇,有没有人在实际代码中观察到两者之间的明显性能差异?我不是专业程序员,我只是在笔记本电脑上测试了一个简单的例子,似乎std::vector 的插入速度确实比std::list 快。不过这似乎有点奇怪......我想了解为什么向量在 STL 实现中更快,

【问题讨论】:

  • 你到底在哪里插入?如果您向我们展示您的基准程序,它会更容易解释。
  • 不,我的意思是你在列表的前面插入?在后面?在随机位置?正好在中间?
  • size()/2,所以在中间,这就是为什么我很困惑......
  • 如果没有您的平台、编译器、优化级别、元素类型的详细信息,这个问题完全没有意义......
  • std::list 和其他基于节点的容器的一个重要问题是缓存使用率低。现代处理器的速度比内存快得多,以至于数据访问组织不当会导致 CPU 花费更多时间等待而不是做有用的工作。

标签: c++ performance c++11 vector stl


【解决方案1】:

由于您没有提供代码示例,我将提供一些可能的原因。

  1. std::list per insert 执行一次动态内存分配,动态内存分配是一项昂贵的操作。 std::list 也需要花费 O(n/2) 时间才能找到中间元素,因为它必须跟随指针而不是只做一个指针相加。
  2. std::vector 将需要将列表末尾的所有元素向右移动,这可能与 std::list 的遍历时间相似或更快。此外,std::vector 在容量用完时往往会翻倍,因此它仅使用 O(log n) 重新分配,而 O(n) 分配给 std::list

如果您开始测量每个容器的更大尺寸,我认为您可能会了解有关复制成本与遍历成本的有趣信息。例如,2000 万个元素。


此外,正如 LightnessRacesinOrbit 正确指出的那样,O(1) 仅表示恒定时间,而 O(n) 表示与输入大小成正比的时间,但这些时间界限不一定转化为实际测量的时间,尤其是对于小型输入,因为O(1) 时间可能隐藏了一个大常数。

但是,我认为对于这个特殊问题,列表遍历可能是罪魁祸首,因为它会导致 O(n) 遍历时间以便插入到列表中间。

【讨论】:

  • 啊,好吧,我认为你是对的。时间基本上是遍历列表,而不是插入本身......因为插入应该是 O(1)。谢谢!但我认为这应该在 C++ 书籍中指出,即使是 Josuttis STL 书籍 cppstdlib.com 也错误地对待它。
  • @vsoftco,不客气。
  • @vsoftco:带有O(1)插入的容器不会自动意味着在x位置插入元素客观上会更快在所有情况下,都比带有 O(n) 插入的容器。一点也不。算法复杂度是关于计算时间相对于n增长,而不是绝对比较。如果常数因子是 3 小时,那么常数时间复杂度对您没有多大帮助。
  • @merlin2011:与 OP 交谈
  • 是的,我明白,我知道常量可以在大 O 表示法中产生巨大的差异,我并不是想学究气,但如果使用 std::vector 似乎比使用 @ 更好,我只是好奇987654338@,至少对于少量元素。
猜你喜欢
  • 2021-10-12
  • 2014-08-23
  • 2021-03-01
  • 2010-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-05
  • 2023-03-22
相关资源
最近更新 更多