在我的DirectX程序中,我编写了一个循环,它遍历std :: string然后我运行了性能分析器并意识到这个循环消耗了极大的cpu时间。当我运行我的程序时,我有大约1300 FPS。所以我决定用这个做点什么,我把基于范围的循环改为典型的迭代。我的意思是我改变了:
for( char c : std_string_name )
到
for(size_t i=0; i<std_string_name.size(); ++i )
{ char c = std_string_name[i]; }
现在我有大约1900 FPS。 这不奇怪吗?
接下来我决定测试迭代器本身,没有任何循环体。下面我给我的测试结果添加了截图链接 str是一个长串, aa,bb,cc是时钟的时间。
void main(){
for(int i=0;i<10;++i)
str += str;
clock_t a, b, c;
clock_t aa, bb, cc;
a=clock();
iter1(str);
aa = clock() -a ;
b=clock();
iter2(str);
bb=clock()-b;
c=clock();
iter3(str);
cc=clock()-c;
}
void iter1( std::string str ){
for( char c : str ){
}
}
void iter2( std::string str ){
for( char &c : str ){
}
}
void iter3( std::string str ){
for( size_t i=0;i<str.length();++i){
char c = str[i];
}
}
aa
获得7017,bb
获得6739,cc
获得1130。
为什么范围循环对性能的影响很慢?你怎么看待这件事?如果有人感兴趣 - 当我通过引用而不是通过值更改传递str时,结果几乎相同。
顺便说一句。我使用MSVS 2012
答案 0 :(得分:6)
(从评论中移出)
基于范围的循环使用迭代器,并且由于额外的调试检查,VC ++迭代器在调试模式下往往很慢;一旦处于发布模式,它们应该归结为指针,因此应该没有性能差异。
此外,您的测试没有意义,因为:
str
);要获得具有统计意义的信息,您必须以随机顺序多次重复测试。答案 1 :(得分:4)
我拿了你的代码写了这个:
#include <iostream>
#include <string>
#include <ctime>
int iter1( std::string str ){
int sum = 0;
for( char c : str ){
sum += c;
}
return sum;
}
int iter2( std::string str ){
int sum = 0;
for( char &c : str ){
sum += c;
}
return sum;
}
int iter3( std::string str ){
int sum = 0;
std::string::size_type len = str.length();
for( size_t i=0;i<len;++i){
char c = str[i];
sum += c;
}
return sum;
}
int main(){
std::string str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
for(int i=0;i<22;++i)
str += str;
clock_t a, b, c;
clock_t aa, bb, cc;
int sum = 0;
a=clock();
sum += iter1(str);
aa = clock() -a ;
b=clock();
sum += iter2(str);
bb=clock()-b;
c=clock();
sum += iter3(str);
cc=clock()-c;
std::cout << "aa=" << aa << " bb=" << bb << " cc=" << cc << " sum=" << sum << std::endl;
}
使用g++ -O2 -Wall -std=c++0x iters.cpp
(gcc 4.6.3)进行编译会得到以下结果:
aa = 320000 bb = 320000 cc = 380000 sum = 1048576000
将优化程度提高到-O3
会产生更大的差异:
aa = 190000 bb = 170000 cc = 450000 sum = 1048576000
请注意,Linux中的“clock”不是很准确,因为它实际上给应用程序使用的CPU时间,它只更新了10ms,因此我不得不使循环更大一些。
很明显你的断言是错误的,因为第三种变体在两种情况下都是SLOWEST。我只能得出结论,你正在以低优化或无优化进行基准测试。