[ACCEPTED]-Efficiency of C-String vs C++Strings-string
C-strings are usually faster, because they 16 do not call malloc/new. But there are cases 15 where std::string
is faster. Function strlen()
is O(N), but 14 std::string::size()
is O(1).
Also when you search for substring, in 13 C strings you need to check for '\0'
on every 12 cycle, in std::string
- you don't. In a naive substring 11 search algorithm it doesn't matter much, because 10 instead of checking for '\0'
you need to check 9 for i<s.size()
. But modern high-performance substring 8 search algorithms traverse strings in multibyte 7 steps. And the need for a '\0'
check in every 6 byte slows them down. This is the reason 5 why GLIBC memmem
is x2 times faster than strstr
. I did 4 a lot of benchmarking of substring algorithms.
This is true not 3 only for substring search algorithm. Many 2 other string processing algorithms are slower 1 for zero-terminated strings.
Why is C++ strings library more efficient? After 21 all, underneath it all, aren't strings still 20 represented as character arrays?
Because 19 the code which uses char*
or char[]
is more likely 18 to be inefficent if not written carefully. For 17 example, have you seen loop like this:
char *get_data();
char const *s = get_data();
for(size_t i = 0 ; i < strlen(s) ; ++i) //Is it efficent loop? No.
{
//do something
}
Is that 16 efficient? No. The time-complexity of strlen()
is 15 O(N)
, and furthermore, it is computed in each 14 iteration, in the above code.
Now you may 13 say "I can make it efficient if I call strlen()
just once.". Of course, you can. But you have to 12 do all that sort of optimization yourself and conciously. If 11 you missed something, you missed CPU cycles. But 10 with std::string
, many such optimization is done by 9 the class itself. So you can write this:
std::string get_data();
std::string const & s = get_data(); //avoid copy if you don't need it
for(size_t i = 0 ; i < s.size() ; ++i) //Is it efficent loop? Yes.
{
//do something
}
Is 8 that efficient? Yes. The time-complexity 7 of size()
is O(1)
. No need to optimize it manually 6 which often makes code look ugly and hard 5 to read. The resulting code with std::string
is almost 4 always neat and clean in comparison to char*
.
Also 3 note that std::string
not only makes your code efficent 2 in terms of CPU cycles, but it also increases 1 programmer efficency!
A std::string
knows its length, which makes many operations 14 quicker.
For example, given:
const char* c1 = "Hello, world!";
const char* c2 = "Hello, world plus dog!";
std::string s1 = c1;
std::string s2 = c2;
strlen(c1)
is slower than 13 s1.length()
. For comparisons, strcmp(c1, c2)
has to compare several 12 characters to determine the strings are 11 not equal, but s1 == s2
can tell the lengths are 10 not the same and return false immediately.
Other 9 operations also benefit from knowing the 8 length in advance, e.g. strcat(buf, c1)
has to find the 7 null terminator in buf
to find where to append 6 data, but s1 += s2
knows the length of s1
already 5 and can append the new characters at the 4 right place immediately.
When it comes to 3 memory management, std::string
allocates additional 2 space every time it grows, which means future 1 append operations don't need to reallocate.
There are some cases in which a std::string
might beat 13 a char[]
. For example, C-style strings typically 12 don't have an explicit length passed around—instead, the 11 NUL terminator implicitly defines the length.
This 10 means that a loop which continually strcat
s onto 9 a char[]
is actually performing O(n²) work, because 8 each strcat
has to process the entire string in 7 order to determine the insertion point. In 6 contrast, the only work that a std::string
needs to 5 perform to concatenate onto the end of a 4 string is to copy the new characters (and 3 possibly reallocate storage—but for the 2 comparison to be fair, you have to know 1 the maximum size beforehand and reserve()
it).
Strings are the object which contain character 20 arrays within themselves along with their 19 size and other functionalities.It is better 18 to use strings from strings library because 17 they save you from allocating and deallocating 16 memory, looking out for memory leaks and 15 other pointer hazards. But as strings are 14 objects, so they take extra space in memory.
Cstrings 13 are simply character arrays. They SHOULD 12 be used when you are working in real time; when 11 you do not know completely about how much 10 memory space you have in hand. If you are 9 using cstrings, you would have to take care 8 for memory allocation, then copying data 7 into it via strcpy or character by character, then 6 deallocating after its usage, etc,etc. So 5 better use strings from string library if 4 you want to avoid a bunch of head aches.
Strings 3 increase program efficiency but reduce processing 2 efficiency(though not necessarily). Vice 1 versa is with cstrings
Well, an obvious and simple thing how they 14 could be practically more efficient (regarding 13 runtime) is, that they store the string's 12 length along with the data (or at least 11 their size
method has to be O(1), which says 10 practically the same).
So whenever you would 9 need to find the NUL character in a C string 8 (and thus walk the whole string once) you 7 can just get the size in constant time. And 6 this happens quite a lot, e.g. when copying 5 or concatenating strings and thus allocating 4 a new one beforehand, whose size you need 3 to know.
But I don't know if this is what 2 the author meant or if it makes a huge difference 1 in practice, but it still is a valid point.
Here is a short point of view.
First of all, C++ strings 13 are objects, so it is more consistent to 12 use them in an object oriented language.
Then, the 11 standard library comes with a lot of useful 10 functions for strings, iterators, etc. All 9 this stuff is stuff you won't have to code 8 again, so you gain time and you're sure 7 that this code is (almost) bugless.
Finally, C 6 strings are pointers, that are kind of difficult 5 to understant when you're new, and they 4 bring complexity. Since references are preferred 3 over pointers in C++, it makes more sens 2 e to use std::string instead of C string.
Hope 1 i helped.
The difficulty with C-style strings is that 44 one really can't do much with them unless 43 one knows about the data structures in which 42 they are contained. For example, when using 41 "strcpy", one must know that the destination 40 buffer is writable, and has enough space 39 to accommodate everything up to the first 38 zero byte in the source (of course, in all 37 too many cases, one doesn't really know 36 that for certain...). Very few library 35 routines provide any support for allocating 34 space on demand, and I think all those that 33 do work by allocating it unconditionally 32 (so if one had a buffer with space for 1000 31 bytes, and one wants to copy a 900-byte 30 string, code using those methods would have 29 to abandon the 1000-byte buffer and then 28 create a new 900-byte buffer, even though 27 it might be better to simply reuse the 1000-byte 26 buffer).
Working with an object-oriented 25 string type would in many cases not be as 24 efficient as working with standard C-strings 23 but figuring out the optimal ways to allocate 22 and reuse things. On the other hand, code 21 which is written to optimally allocate and 20 reuse strings may be very brittle, and slight 19 changes to requirements could require making 18 lots of tricky little tweaks to the code--failing 17 to tweak the code perfectly would likely 16 result in bugs which may be obvious and 15 severe, or subtle but even more severe. The 14 most practical way to avoid brittleness 13 in code which uses standard C strings is 12 to design it very conservatively. Document 11 maximum input-data sizes, truncate anything 10 which is too big, and use big buffers for 9 everything. Workable, but not terribly 8 efficient.
By contrast, if one uses the object-oriented 7 string types, the allocation patterns they 6 use will likely not be optimal, but will 5 likely be better than the 'allocate everything 4 big' approach. They thus combine much of 3 the run-time efficiency of the hand-optimized-code 2 approach with safety that's better than 1 the 'allocate everything big' approach.
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.