关于char *和string的效率比较
zhjhe 2003-02-11 10:40:46 昨天本人发了“我是教条主义者,请大家将标准C++进行到底”的帖子,网友对其中的一个细节---char *和string的效率---提出了不同看法,现回答如下:
Cybergate:您让我看《The c++ programming language题解》,但没有指明是那个地方,我姑且猜测是练习20。1(不知看对了没有)。
//两个string版本的
string dotconnect (string const &a, string const &b)
{
return a + '.' + b;
}
string dotconnect (string const &a, string const &b)
{
string result(a.size() + b.size() + 1, '.');
result.replace(0, a.size(), a);
result.replace(a.size() + 1, b.size(), b);
reutrn result;
}
//C风格版本的
char * dotconnect (char const *a, char const *b)
{
size_t alen = strlen(a), blen = strlen(b);
char *result = (char *) malloc(alen + blen + 2);
memcpy (result, a, alen);
result[alen] = '.';
memcpy (result + alen + 1, b, blen);
result[alen + blen + 2] = '\0';
return result;
}
作者提到,c风格的版本比string的第二个版本快了大约4倍,但是,正如作者所暗示的,这是一个不公平的测试,下面是另外一个更加不公平的测试,来自《C++ Primer》p82练习3。14。
int main ()
{
int errors = 0;
const char *pc = "a very larg literal string";
for (int ix = 0; ix < 1000000; ++ ix)
{
int len = srlen (pc);
char *pc2 = new char[len + 1];
strcpy (pc2, pc);
if (strcmp (pc2, pc))
++ errors;
delete pc2;
}
}
int main ()
{
int errors = 0;
string str("a very larg literal string");
for (int ix = 0; ix < 1000000; ++ ix)
{
int len = str.size();
string str2 = str;
if (str != str2)
++ errors;
}
}
这里的string版本比char *版本的快两倍。
不公平的大约是这两条语句。
int len = strlen(pc);
int len = str.size();
由于string显式存储长度,而strlen通过遍历整个串来确定长度,所以在执行了1000000次之后,两者的快慢显示出来了。
关于效率的问题,《题解》181面有着较为详细的分析,经过一番考虑后,我认为使用string代替char *,不仅能让我们避免很多麻烦,而且也不会丧失效率,甚至能提高我们的程序的效率(当然,如果您能确定不会出错而且效率问题很重要的话,我也不反对您使用char *)。
实际上各个不同的实现也有着不同的效率,原则上string可以有着非常高的效率,所以,不要简单的认为string的效率不如char *.
再次提倡大家使用 string。同是欢迎任何对我的批评。