性能 - 使用迭代器或指针迭代向量?
Posted
技术标签:
【中文标题】性能 - 使用迭代器或指针迭代向量?【英文标题】:Performance - iterating over vector with iterator or pointer? 【发布时间】:2013-03-13 07:54:13 【问题描述】:我目前正在编写一个需要尽可能好地执行的应用程序。我使用 VS2012 作为我的 IDE(和编译器)。
我注意到,当我对向量进行迭代时,与迭代器相比,指针解决方案在速度方面要快得多。这是为什么?我的意思是,迭代器基本上是一样的。至少应该是。
看看这个例子:
std::vector<int> v;
for (std::vector<int>::iterator it = v.begin(); it != v.end(); it++)
// Do stuff with *it
for (int* i = &v[0], i <= &v[v.size()-1]; i++)
// Do stuff with *i
编译器是否需要任何优化?我正在使用所有标准设置,所以 -O2 已经启用。提前致谢。
编辑: 我在 Release 中编译,并使用 Ctrl+F5 运行(即没有调试)。
EDIT2: 实际的源代码是快速排序的实现。 Here is a link to the full source,很短,请查看。
【问题讨论】:
你可能在调试模式下编译,迭代器执行断言。 看看调试生成的汇编代码和优化生成的代码之间的区别。 您的分析如何?循环中发生了什么?你用的是哪个编译器? 我用的是VS2012自带的最新MSVC。 检查_ITERATOR_DEBUG_LEVEL的设置。 【参考方案1】:我目前正在编写一个需要尽可能好地执行的应用程序。
然后使用分析器查看真正的瓶颈在哪里。当然是在优化代码(发布模式)中。
-O2 并不是 VS2012 中的全部:有几个 #defines
可以操纵标准容器迭代器的行为,包括边界检查和其他安全检查。您可能想要查找它们(“检查迭代器”和“安全 SCL”可能会引导您到正确的站点)并相应地设置它们。
但我非常怀疑容器上的迭代是否会成为您的瓶颈,会有其他代码部分对性能问题更敏感。
【讨论】:
【参考方案2】:一个潜在的原因是您正在对迭代器进行后递增,而不是对其进行预递增。试试这个:
for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it)
这可能不会提高您的速度,因为一些(也许是大多数)编译器优化了这个问题。但是,有时当您进行后增量时,必须制作旧迭代器值的临时副本,以允许它在循环中返回您期望的值。无论如何都要尝试一下。
【讨论】:
【参考方案3】:提高性能的一种简单方法是不要在每次迭代中都使用end
方法 - 也不要使用++it
而不是it++
。
即
std::vector<int> v;
const std::vector<int>::iterator end = v.cend();
for (std::vector<int>::iterator it = v.begin(); it != end; ++it)
// Do stuff with *it
【讨论】:
从实际测量结果来看(使用 g++,而不是 VC++),无论您使用++ i
还是 i ++
都无关紧要。但是,将调用移到循环之外的end()
确实会产生可衡量的差异。并且在 C++11 之前的版本中,使用 const 迭代器也可以避免类型转换(如果 v.end()
返回一个非常量迭代器)。由于这些原因,我开始写for ( std::vector<int>::const_iterator current = v.begin(), end = v.end(); current != end; ++ current )
。以上是关于性能 - 使用迭代器或指针迭代向量?的主要内容,如果未能解决你的问题,请参考以下文章