最近寫的程序用到大量拼接字符串,為了提高拼接效率,比較了一下+=、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()。
——菜鳥吉姆斯原創,如有錯誤,敬請指正!