【发布时间】:2012-03-19 08:18:20
【问题描述】:
我有疑问纠正我对通过使用索引访问(使用运算符 [])或使用迭代器访问向量元素的效率的理解。
我的理解是“迭代器”比“索引访问”更有效。
(我也认为vector::end() 比vector::size() 更有效)。
现在我编写了示例代码来测量它(在 Windows 7 下使用 Cygwin,使用 g++ 4.5.3)
索引访问循环版本(以前标记为随机访问):
int main()
{
std::vector< size_t > vec ( 10000000 );
size_t value = 0;
for( size_t x=0; x<10; ++x )
{
for ( size_t idx = 0; idx < vec.size(); ++idx )
{
value += vec[idx];
}
return value;
}
}
迭代器循环代码是这样的:
for (std::vector< size_t >::iterator iter = vec.begin(); iter != vec.end(); ++iter) {
value = *iter;
}
我很惊讶地发现“索引访问”版本要快得多。我使用time 命令来“测量”。数字是:
使用
g++ source.cpp的结果(无优化) 索引访问真正的 800 毫秒
迭代器访问
真正的 2200 毫秒
这些数字有意义吗? (我多次重复运行)我想知道我错过了哪些细节以及为什么我错了......
使用 g++ -O2 的结果 索引访问,实际时间:~200ms
迭代器访问,实际时间:~200ms
我在不同平台(amd64 w/g++ 和 power7 w xlC)上重复测试,发现我一直使用优化代码,示例程序的执行时间相似。
edit 更改了代码以添加值 (value += *iter),而不仅仅是使用赋值。添加了有关编译器选项的详细信息。添加了使用 -O2 的新数字。
*edit2 将标题更正“迭代器效率”更改为“访问效率”。
【问题讨论】:
-
确保您没有使用调试支持进行编译,尤其是在 MSVC 下。此外,您的第一个版本根本不使用迭代器,而在第二个版本中,您确实拥有随机访问迭代器。
-
你开启优化了吗?
-
你的预感是正确的,经过优化是相反的,#2 更快。
-
我觉得你很困惑。 Vector 只有随机访问迭代器。使用
operator[]对向量进行索引不涉及迭代器。 -
替换值 = vec[idx];值 += vec[idx];在这两种情况下,为了避免编译器太聪明以至于发现它被覆盖了