They should be equivalent in general, though std::string
might be a tiny bit slower. Why? Because of short-string optimization.
Short-string optimization is a trick some implementations use to store short strings in std::string
without allocating any memory. Usually this is done by doing something like this (though different variations exist):
union {
char* data_ptr;
char short_string[sizeof(char*)];
};
Then std::string
can use the short_string
array to store the data, but only if the size of the string is short enough to fit in there. If not, then it will need to allocate memory and use data_ptr
to store that pointer.
Depending on how short-string optimization is implemented, whenever you access data in a std::string
, it needs to check its length and determine if it's using the short_string
or the data_ptr
. This check is not totally free: it takes at least a couple instructions and might cause some branch misprediction or inhibit prefetching in the CPU.
libc++ uses short-string optimization kinda like this that requires checking whether the string is short vs long every access.
libstdc++ uses short-string optimization, but they implement it slightly differently and actually avoid any extra access costs. Their union is between a short_string
array and an allocated_capacity
integer, which means their data_ptr
can always point to the real data (whether it's in short_string
or in an allocated buffer), so there aren't any extra steps needed when accessing it.
If std::string
doesn't use short-string optimization (or if it's implemented like in libstdc++), then it should be the same as using a char*
. I disagree with black's statement that there is an extra level of indirection in this situation. The compiler should be able to inline operator[]
and it should be the same as directly accessing the internal data pointer in the std::string
.