Gal*_*man 57 c++ performance iterator stl vector
在性能方面,什么会更快?有区别吗?它是平台依赖的吗?
//1. Using vector<string>::iterator:
vector<string> vs = GetVector();
for(vector<string>::iterator it = vs.begin(); it != vs.end(); ++it)
{
*it = "Am I faster?";
}
//2. Using size_t index:
for(size_t i = 0; i < vs.size(); ++i)
{
//One option:
vs.at(i) = "Am I faster?";
//Another option:
vs[i] = "Am I faster?";
}
Run Code Online (Sandbox Code Playgroud)
tst*_*ner 36
使用迭代器会导致递增指针(用于递增)和解除引用以取消引用指针.
对于索引,递增应该同样快,但查找元素涉及添加(数据指针+索引)和解除引用该指针,但差异应该是边际的.
at()还会检查索引是否在边界内,因此可能会更慢.
500M迭代的基准测试结果,矢量大小10,gcc 4.3.3(-O3),linux 2.6.29.1 x86_64
at():: 9158ms
operator[]:4269ms
iterator:3914ms
YMMV,但是如果使用索引使代码更易读/可理解,那么你应该这样做.
小智 27
为什么不写一个测试并找出来?
编辑: 我的坏 - 我以为我是优化版本的计时但不是.在我的机器上,用g ++ -O2编译,迭代器版本比operator []版本略慢,但可能不是那么明显.
#include <vector>
#include <iostream>
#include <ctime>
using namespace std;
int main() {
const int BIG = 20000000;
vector <int> v;
for ( int i = 0; i < BIG; i++ ) {
v.push_back( i );
}
int now = time(0);
cout << "start" << endl;
int n = 0;
for(vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
n += *it;
}
cout << time(0) - now << endl;
now = time(0);
for(size_t i = 0; i < v.size(); ++i) {
n += v[i];
}
cout << time(0) - now << endl;
return n != 0;
}
Run Code Online (Sandbox Code Playgroud)
xto*_*ofl 15
如果您不需要索引,请不要使用它.迭代器概念是最好的.迭代器非常容易优化,而直接访问需要一些额外的知识.
索引用于直接访问.括号和at方法执行此操作. at将不会[]检查越界索引,因此它会更慢.
信条是:不要问你不需要什么.然后编译器不会向您收取您不使用的内容.
Jam*_*kin 14
既然您正在考虑效率,那么您应该意识到以下变化可能更有效:
//1. Using vector<string>::iterator:
vector<string> vs = GetVector();
for(vector<string>::iterator it = vs.begin(), end = vs.end(); it != end; ++it)
{
//...
}
//2. Using size_t index:
vector<string> vs = GetVector();
for(size_t i = 0, size = vs.size(); i != size; ++i)
{
//...
}
Run Code Online (Sandbox Code Playgroud)
因为end/size函数只调用一次而不是每次调用循环.编译器很可能无论如何都会内联这些函数,但这种方式可以确保.
我猜第一个变体更快。
但这取决于实施。为确保您应该分析您自己的代码。
为什么要分析自己的代码?
因为这些因素都会改变结果:
正如这里的其他人所说,做基准测试.
话虽如此,我认为迭代器更快,因为at()也会进行范围检查,即如果索引超出范围,它会抛出一个out_of_range异常.检查本身可能会产生一些开销.