C风格的string和C++风格的string运行效率的问题
最近在看《C++ Primer》,其中82页有这样一个例子:
C风格的字符串程序:
int main(int argc, char* argv[])
{
int errors=0;
const char *pc="a verry long literal string";
for (int ix=0;ix<1000000;++ix)
{
int len=strlen(pc);
char *pc2=new char[len+1];
strcpy(pc2,pc);
if (strcmp(pc2,pc))
++errors;
delete []pc2;
}
cout <<"C-style character string:"<<errors<<" errors occured.\n";
return 0;
}
用C++的string实现:
int main(int argc, char* argv[])
{
int errors=0;
sring str="a verry long literal string";
for (int ix=0;ix<1000000;++ix)
{
int len=str.size();
string str2=str;
if (str!=str2)
++errors;
}
cout <<"String class:"<<errors<<" errors occured.\n";
return 0;
}
然后作者问,平均来说string类型实现的执行速度是C风格字符串的两倍,在一台UNIX机器上,前一个程序用时1.98秒,后一个是0.96秒,请说明原因?
我觉得C++风格的string应该开销要大些,为什么反而执行速度快?
问题点数:50、回复次数:6Top
1 楼healer_kx(甘草(楼主揭贴吧,我们这些上班灌水的也不容易))回复于 2006-08-10 11:16:08 得分 0
所谓开销是一种直觉而已, 你可以认为C++的string用了空间换得了时间.
而且还有稳定性.Top
2 楼a_b_c_abc2(WeCallARoseByAnyOtherWordWouldSmellAsSweet)回复于 2006-08-10 11:27:31 得分 0
造成C风格字符串运行速度不如C++的string类型的原因,其实关键在这句:
int len=strlen(pc);//每次都要遍历串,如果在for前用一个变量保存,应该不会比string类型慢
Top
3 楼a_b_c_abc2(WeCallARoseByAnyOtherWordWouldSmellAsSweet)回复于 2006-08-10 11:54:27 得分 20
看来是我下结论太早。
经实验,VC debug版本下string总是要慢点,而Release版本下string快三倍。
而且也不是因为C风格字符串的for循环中有int len=strlen(pc);,这句对速度的影响很小。
关键在构造速度,将C风格字符串改为这样就赶得上string了:
c=clock();
int errors=0;
const char *pc="a verry long literal string";
int len=strlen(pc);
char *pc2=new char[len+1];
strcpy(pc2,pc);
for (int ix=0;ix<1000000;++ix)
{
//int len=strlen(pc);
//char *pc2=new char[len+1];
//strcpy(pc2,pc);
if (strcmp(pc2,pc))
++errors;
//delete []pc2;
}
delete []pc2;
cout <<"C-style character string:"<<errors<<" errors occured.\n";
cout<<(clock()-c)<<endl;Top
4 楼fflush(stdin)回复于 2006-08-10 12:02:26 得分 20
a_b_c_abc2() 说到了点子上,实际上stl的string采用引用计数技术,对拷贝实行copy on write的策略,也就是说在string的测试例子中
string str2=str;
if (str!=str2)
++errors;
由于并没有对str2中的字符串进行任何修改,所以实际上str和str2共用了同一段buffer,换句话说,这里并没有任何字符串拷贝的发生。因此,如果进行a_b_c_abc2()所说的修改,两者性能将相似。Top
5 楼chenhu_doc(^0^纯一狼^0^ 看书看到大笑,直到不能自已)回复于 2006-08-10 12:03:23 得分 0
http://community.csdn.net/Expert/topic/4739/4739428.xml?temp=.1827967
一样的问题。。。Top
6 楼a_b_c_abc2(WeCallARoseByAnyOtherWordWouldSmellAsSweet)回复于 2006-08-10 12:05:18 得分 10
原来string是“写时复制”的,如果str2没有改变,str2就没在真正在内存中构造。
只要在构造后加一句str2[0]='A';,整个程序的运行时间就与C风格字符串程序相当了。
{
int c;
c=clock();
int errors=0;
string str="a verry long literal string";
for (int ix=0;ix<1000000;++ix)
{
int len=str.size();
string str2=str;
str2[0]='A';//加这句,整个程序的运行时间就与C风格字符串程序相当了。
if (str!=str2)
++errors;
}
cout <<"String class:"<<errors<<" errors occured.\n";
cout<<(clock()-c)<<endl;
}Top




