//C-style character string implementation
constchar *pc = "a very long literal string";
const size_t len = strlen(pc + 1); //space to allocate
//performace test on string allocation and copy
for(size_t ix = 0; ix !=1000000; ++ix)
{
char *pc2 = newchar[len + 1]; //allocate the space
strcpy(pc2, pc); //do the copy
if(strcmp(pc2, pc)) //use the new string
; //do nothing
delete [] pc2;
}
//string implementation
string str("a very long literal string");
//performance test on string allocation and copy
for(int ix = 0; ix !=1000000; ++ix)
{
string str2 = str; //do the copy, automatically allocated
if(str != str2) //use the new string
; //do nothing
}
*Program is for illustrative purposes.
I get that c++ library strings are easy to implement, less error prone, etc. But I would figure that in some cases the raw implementation of c-style strings would outperform their library counterparts. Are their cases where c-style is preferred? Some insight would be appreciated.
many developers have spent many hours fine tuning std::string for speed and efficiency. On large scale operations like the above, your code is unlikely to beat it.
Old style C char arrays are only likely to be better for simpler operations, where using a std::string would be equivalent to a sledge hammer to crack a nut, or the cost of instantiating a std::string is not worth it just to copy a couple of chars around.
I believed std::string to definitely be more efficient in terms of code length, but I thought that this came at a cost. I thought for something as basic as allocation and copying there wouldn't be such a significant improvement. But in fact on my computer the difference is almost 3 fold in favor of std::string!
I do like the sledge hammer anaolgy. ;p
A slege hammer would work through a slab of concrete in no time, but a regular hammer would take forever!
I wonder if the analogy would still hold up in the case of many tiny nuts; a sledge hammer would take care of it but it would be harder to move around and get going, whileas the smaller hammer would be easier to manipulate and be better suited for the task...
[apologies ahead of time if that didn't make sense :p]
There are many implementations of the std library just like there are many compilers. The only requirements for it to be std library compatible really are the methods available and the behaviours under specified conditions. I should point out that these specifications are extensive, not just a couple of pages. Beyond that it is down to the person writing the code.
The variations in speed between the std library and C style operations are wholly dependent on which library you are using (who wrote it), which compiler you are using and which platform you are running on.
My comment above still holds true in general but there will always be combinations of library and compiler that prove to be an exception.
some implementations may allocate a fixed (stacked) initial buffer and only use the heap if more memory is needed
the implementation you used may be avoiding the whole new and delete process, or may be using a memory pool (which also avoids new and delete for almost all constructions and destructions)
Many string implementations use copy-on-write semantics.
In your example,
string str2 = str;
is equivalent to
string str2( str );
ie, it runs string's copy constructor which, rather than copying the whole "char array", just copies a pointer to the array. The deep copy is made only when one of the two strings is written to. Thus, in your example, the C version copies far more bytes than the C++ /std::string version, and this is why you see the performance improvement.