Skip to content

performance tuning with std::string

Sunday, 10 September 2006  |  alexander neundorf

So today I tried to optimize some code using std::string from the Standard Template Library and found something interesting.

Let's say you have strings to assign which sometimes get longer and then again shorter. To avoid unnecessary memory allocations you can use std::string::resize(size_t n); so you create the string and then resize it so that it is big enough for the longest string:

std::string s0;
s0.resize(512);   
std::string s1="hello";
std::string s2="";
std::string s3="big";
std::string s4="";
std::string s5="world";
s0=s1;
s0=s2;
s0=s3;
s0=s4;
s0=s5;

So everything is handled as std::string and you might think everything's fine. But you could also do the following:

std::string s0;
s0.resize(512);   
std::string s1="hello";
std::string s2=" ";
std::string s3="big";
std::string s4=" ";
std::string s5="world";
s0=s1.c_str();
s0=s2.c_str();
s0=s3.c_str();
s0=s4.c_str();
s0=s5.c_str();

Here everytime a standard C null-terminated string is assigned. You could think that this is slower, among others because the length is unknown and so during assignment either strlen() has to be called or every byte has to be checked for 0.

But, wrong ! This second option is indeed faster. The difference is, that when assign a std::string to another std::string it also assigns the capacity. This means that in the first example the resize(512) is useless, because with the first assignment this is lost and the capacity goes down, after the second assignment the capacity is even further down, so that for the third assignment memory will be allocated. When assigning null-terminated C strings, the capacity stays at 512, so no memory is allocated or freed. Result: assigning the c_str() is faster !

Alex