Reputation: 601
I have seen char* vs std::string in c++, but am still wondering if accessing the elements of a char*
is faster than std::string
.
If you need to know, the char*
/std::string
will contain less than 80 characters, but I would like to know a cutoff if there is one.
I would also like to know the answer to this question for different compilers and different Operating Systems, if there is a difference.
Thanks in advance!
Edit: I would be accessing the elements using array[n]
, and would set the values once.
(Note: If this doesn't meet the help center, please let me know how I can reword it before down-voting)
Upvotes: 2
Views: 556
Reputation: 38218
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
.
Upvotes: 6
Reputation: 8494
Since you don't have direct access to the underlying CharT
sequence, accessing it will require an extra layer through the public interface. So it could be slower, probably requiring 20-30 cycles more. Even then, only in a tight loop you might see a difference.
However, it's extremely easy to optimize this out considering the large range of techniques a compiler can employ (caching, inlining, non-standard function calls and so on) if you instruct it to.
Upvotes: 3