最近写的程序用到大量拼接字符串,为了提高拼接效率,比较了一下+=、append、stringstream、sprintf四种拼接字符串的方法。
测试方法
比较方法是写了4个函数,分别用+=、append、stringstream、sprintf的方式来拼接字符串,拼接方法是将s1="abcedfg",s2="hijklmn",s3="opqrst"三个字符串拼接到一起,总共循环60次。然后在main函数中依次调用这4个函数,并打时间戳来计时。为了使时间差异更明显,可以取循环N(N可以为100或是1000000等)次调用的时间。代码如下:
1 #include <iostream> 2 #include <string> 3 #include <sys/time.h> 4 #include <sstream> 5 #include <stdio.h> 6 using namespace std; 7 #define OUT_IN_REPEATE_NUM 10000 8 #define IN_REPEATE_NUM 60 9 10 string s1="abcedfg"; 11 string s2="hijklmn"; 12 string s3="opqrst"; 13 void plusTest(string& ret) 14 { 15 for(int i=0; i<IN_REPEATE_NUM; i++) 16 { 17 ret += s1; 18 ret += s2; 19 ret += s3; 20 } 21 } 22 void appendTest(string& ret) 23 { 24 for(int i=0; i<IN_REPEATE_NUM; i++) 25 { 26 ret.append(s1); 27 ret.append(s2); 28 ret.append(s3); 29 } 30 } 31 void sprintfTest(string& ret) 32 { 33 const size_t length=26*IN_REPEATE_NUM; 34 char tmp[length]; 35 char* cp = tmp; 36 size_t strLength=s1.length()+s2.length()+s3.length(); 37 for(int i=0; i<IN_REPEATE_NUM; i++) 38 { 39 sprintf(cp,"%s%s%s", s1.c_str(), s2.c_str(),s3.c_str()); 40 cp+=strLength; 41 } 42 ret = tmp; 43 } 44 45 void ssTest(string& ret) 46 { 47 stringstream ss; 48 for(int i=0; i<IN_REPEATE_NUM; i++) 49 { 50 ss<<s1; 51 ss<<s2; 52 ss<<s3; 53 } 54 ret = ss.str(); 55 } 56 int main() { 57 string ss, plus, append, sprintf; 58 struct timeval sTime, eTime; 59 60 gettimeofday(&sTime, NULL); 61 for(int i=0; i<OUT_IN_REPEATE_NUM; i++) 62 { 63 sprintf=""; 64 sprintfTest(sprintf); 65 } 66 gettimeofday(&eTime, NULL); 67 long SprintfTime = (eTime.tv_sec-sTime.tv_sec)*1000000+(eTime.tv_usec-sTime.tv_usec); //exeTime 单位是微秒 68 69 gettimeofday(&sTime, NULL); 70 for(int i=0; i<OUT_IN_REPEATE_NUM; i++) 71 { 72 append=""; 73 appendTest(append); 74 } 75 gettimeofday(&eTime, NULL); 76 long AppendTime = (eTime.tv_sec-sTime.tv_sec)*1000000+(eTime.tv_usec-sTime.tv_usec); //exeTime 单位是微秒 77 78 gettimeofday(&sTime, NULL); 79 for(int i=0; i<OUT_IN_REPEATE_NUM; i++) 80 { 81 ss=""; 82 ssTest(ss); 83 } 84 gettimeofday(&eTime, NULL); 85 long SsTime = (eTime.tv_sec-sTime.tv_sec)*1000000+(eTime.tv_usec-sTime.tv_usec); //exeTime 单位是微秒 86 87 gettimeofday(&sTime, NULL); 88 for(int i=0; i<OUT_IN_REPEATE_NUM; i++) 89 { 90 plus=""; 91 plusTest(plus); 92 } 93 gettimeofday(&eTime, NULL); 94 long PlusTime = (eTime.tv_sec-sTime.tv_sec)*1000000+(eTime.tv_usec-sTime.tv_usec); //exeTime 单位是微秒 95 96 cout<<"PlusTime is : "<<PlusTime<<endl; 97 cout<<"AppendTime is : "<<AppendTime<<endl; 98 cout<<"SsTime is : "<<SsTime<<endl; 99 cout<<"SprintfTime is :"<<SprintfTime<<endl; 100 if(ss==sprintf && append==plus && ss==plus) 101 { 102 cout<<"They are same"<<endl; 103 } 104 else 105 { 106 cout<<"Different!"<<endl; 107 cout<<"Sprintf: "<<sprintf<<endl; 108 cout<<"ss: "<<ss<<endl; 109 cout<<"Plus: "<<plus<<endl; 110 cout<<"Append:"<<append<<endl; 111 } 112 113 }
测试结果:
在Linux环境下用g++编译以上代码,运行结果如下(时间单位为μm):
外层循环1000000次 |
外层循环100000次 |
外层循环10000次 |
外层循环1000次 |
外层循环100次 |
PlusTime is : 3405450 AppendTime is : 4020078 SsTime is : 7835499 SprintfTime is : 14875433 They are same |
PlusTime is : 337229 AppendTime is : 401719 SsTime is : 788242 SprintfTime is : 1517999 They are same |
PlusTime is : 32177 AppendTime is : 40265 SsTime is : 78928 SprintfTime is : 150839 They are same |
PlusTime is : 3402 AppendTime is : 4074 SsTime is : 7984 SprintfTime is : 15425 They are same |
PlusTime is : 369 AppendTime is : 429 SsTime is : 921 SprintfTime is : 1591 They are same |
结论:
根据以上结果,如果是使用Linux系统并且是g++(gcc)编译器,大量拼接字符串的效率从高到低依次为:+=、append()、stringstream、sprintf()。
——菜鸟吉姆斯原创,如有错误,敬请指正!