Copy-on-write string performance
Since I’ve started using Qt, I loved the “implicit sharing” concept it uses for it’s strings and container types. It become so much easier to pass these data around. I wasn’t aware that some STL implementations have copy-on-write semantics for strings as well. When I saw some recommendations for std::string
on Stack Overflow, I’ve decided to check out the implementation in GCC and discovered that it indeed does some reference counting.
So the next step was comparing the implementations. I wrote a little program today to check how QString
and std::wstring
compare in terms of copy-on-write performance. Since QChar
is 2 bytes and wchar_t
is 4 bytes on my machine, it wouldn’t be completely fair comparison, so I’ve included also std::string
. The results were quite surprising for me. STL does almost always better, but for some reason I wasn’t able to make not dereference the string on read-only operations.
wchar_t* QString std::wstring std::string
Read
0 ms
0 ms
2143 ms
2224 ms
Write
0 ms
5588 ms
2621 ms
2570 ms
Copy
1618 ms
601 ms
116 ms
117 ms
Copy + read
-
601 ms
6161 ms
5079 ms
Copy + write
-
11036 ms
6822 ms
6843 ms
Copy + append
-
5801 ms
4650 ms
3482 ms
The table shows times in milliseconds for 10000000 repeated operations on a 200-character long string.
- “Read” just reads the string one character at a time, using the default
[]
operator. I’ve tried hard to find a cheaper way to do this for STL strings, but I failed (I wasn’t interested in usings.data()
and then working with the primitive array, I wanted to work with the object directly). - “Write” writes to all characters of the string, again one character at a time.
- “Copy” assigns one string to another, using the default
=
operator for string classes andmemcpy
forwchar_t*
. - “Copy + read” is the same as “Copy”, followed by “Read” performed on the copy.
- “Copy + write” is the same as “Copy”, followed by “Write” performed on the copy.
- “Copy + append” is again the same as “Copy”, followed by appending a short string to the copy.
I guess I should note that this wasn’t meant to be a generic benchmark of the string classes. I just wanted to know performance details about the copy-on-write implementations in them. The conclusion for me is that the STL strings in GCC are better than I always thought, but the fact that they dereference the data on read-only operations is not very nice.