标准向量和Boost数组:哪个更快?

16

boost::array 的性能与 std::vector 相比如何,并且哪些因素对其有重要影响?


3
@Benoit. 我从事科学计算,速度非常重要。 - grzkv
10
你应该知道如何进行剖析分析。 - GManNickG
1
@Roman:那么内存分配和重新分配将是您唯一真正的瓶颈。如果您知道要存储多少元素,请从其中一个开始,例如使用std::vector::reserve - Benoit
4
@Roman,一个是在编译时限制的,另一个则具有根据需要灵活增长的能力 - 您需要哪个? - Nim
3
boost::array 可以静态或动态分配内存(即在栈或堆上)。而 std::vector 的存储总是动态分配的,即使向量是静态分配的。 - KeithB
显示剩余3条评论
4个回答

32

boost::array(或C++0x的std::array)应该比std::vector更快,因为boost::array实例完全位于堆栈上。这意味着boost::array没有堆分配,也意味着它不能超过在构造函数中指定的大小。

boost::array的目的是作为围绕原始数组的薄层,以便您可以将它们视为具有.begin().end()等标准容器。好的编译器应该消除boost::array的所有开销,使其表现与原始数组相同。


所有这些都涉及“默认”设置,其中您没有自定义分配程序,并且您测量诸如数组构造,访问和修改元素之类的简单事物。另一方面,在其他测试,其他平台或精明的设置下事情可能会发生变化。例如,

  • 如果创建自定义分配器,可能在程序启动时获取大型内存池,则构造或调整std::vector可能不再那么昂贵。
  • 交换一个std::vector与另一个通常是非常快的操作;交换两个指针的速度。交换两个boost::array实例可能会更加昂贵;大约为复制n个元素。但是,在C++0x中,其中std::array将是一部分,再次交换两个数组将很快,这要归功于右值引用及其移动语义。
  • 复制向量可能是非常快的操作;像复制指针一样快(写时复制)。复制boost::array可能需要复制每个数组元素。不过,有时复制任何对象都非常快,甚至比复制指针还要快,甚至在您的C++03编译器中--这要归功于复制省略。

您可以进行分析以查看哪个适合您的用途,但即使进行此测试,它也只会为特定版本的特定编译器在特定平台上提供一个想法。


1
听起来你不能在大数组大小时使用boost :: array。否则你会冒着堆栈溢出的风险。对吗? - ypnos
2
如果你在栈上分配它,@Ypnos,那么是的,你可以期望堆栈溢出(或者编译器错误,如果编译器禁止超过某个大小的类型)。如果你动态分配,那么除非你错误地按值传递数组,否则不应该出现堆栈溢出。(但无论你在哪里分配值,编译器错误仍然是一个风险。) - Rob Kennedy
5
更快的是做什么?这个问题原本就含糊不清。他是指访问数组/向量成员还是指填充/分配相同的工作速度? - Jon Trauntvein
@JonTrauntvein 我已经表明了我的假设。 - wilhelmtell
在我看来,给出带有明确假设的答案比回答“那取决于情况”并停止不说更有帮助。 - wilhelmtell
无论您使用的标准版本是什么,std::vector 都不能进行写时复制(COW),因为这违反了迭代器失效规则。 - T.C.

17

通过编写大量数据的程序来测试性能是得出任何结论的最佳方法。否则,你怎么能得出任何结论呢?

在此过程中,您可能需要一些工具来帮助您,例如VTuneAMD CodeAnalyst Performance Analyzer等。 Very Sleepy(免费工具)是用于Windows系统的C/C++ CPU分析器。 您可以尝试使用它们!


嘿,Very Sleepy 是一个不错的小工具!(我已经更正了它的链接。) - Nate

12

更快的是什么?std::vector更快打字因为它少了一个字符。

速度快不重要,你在比较两个不同的东西,静态大小的数组和动态大小的数组。使用哪个取决于你的应用程序,与速度无关。

你想开飞机还是开车去某个地方?这取决于更多的因素,而不仅仅是“速度”。


boost::array可能更快分配内存,因为它通常在堆栈上。或者std::vector可能会有一些自定义的内存分配方案,所以也很快。

但这只涉及到分配内存。使用呢?这两个都只是数组的索引,所以没有区别。但是移动或交换呢?boost::array肯定不能像std::vector那样快速进行移动或交换,因为std::vector只需要移动/交换指针。或者也许不是,谁知道呢?

你必须对其进行剖析并查看汇编代码。没有人可以神奇地知道事物在你的应用程序中的执行效率。


如果您有大量数据需要处理,分配std::vector所需的时间很容易被遍历已分配数据所需的时间所淹没。特别是如果您开始对数据进行多次遍历。 - SirGuy

2

arrayvector 的用途略有不同。如果你初始化一个大小恰当的 vector,并且它不会被重新分配内存,则两者之间的性能相同。 array 仅处理静态大小数组(如果您愿意,可以说是C风格数组)。vector 可以在向容器中添加更多对象时增长,以容纳超出其容量的对象。


因为向量需要通过指针访问底层数据,所以数组可能会有轻微的性能优势,因为向量访问将不得不通过一个更高级别的间接访问。我怀疑这在现代硬件上除了极端情况外,不值得考虑。 - Ferruccio
他所说的不是C风格数组,而是指std::array(又名boost::array)模板类,其重定向性能“损失”与向量相同(两者都非常微小,无关紧要)。 - Zac Howland

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接