15

I am migrating an old code base from using a custom implementation of strings to use std::string. One of our engineers is concerned that this could lead to a performance issue where we are using += and + to concatenate relatively long strings. His particular concern is how the memory is allocated as the string grows dynamically, and he suggested that stringstream would perform better in this regard. For those of you tempted to respond "benchmark then optimize" or sentiments to those effect -- I do of course agree, and that's the plan. I'm just wondering about the theory.

I did a little searching for this issue, and ran into this question: Efficient string concatenation in C++, which is getting a little dated.

Now I'm wondering: Is the memory allocation algorithm for string += really different than that for string stream? What about the copy issues raised in the above question -- have these changed with c++ 11/14?

2
  • 4
    Here is a newer question stackoverflow.com/questions/18892281/… with a nice answer using c++11 complete with benchmarks. It seems to test quite short strings, so you may want to adapt the benchmark for yourself. Edit, oh, another answer does do longs strings. Commented Jun 23, 2015 at 13:08
  • There are two parts to this question: (1) string length by NUL scanning (possibly done repeatedly), (2) repeated re-allocations (growth). First part is solved by using std::string, which memorizes the length. Second part is solved by calling std::string::reserve if a reasonable upper bound on total length can be estimated. Reasonable means that over-estimate is acceptable if the excess is not excessive. Commented Oct 19, 2016 at 17:51

1 Answer 1

12

Is the memory allocation algorithm for string += really different than that for string stream?

Yes.

A stringstream writes into a stringbuffer, which usually means a linked list of buffers. Memory is not continuous, and it requires no reallocations as the buffer grows.

A string on the other hand, allocates memory in a single block (as needed, and sometimes preemptively).

The most efficient solution is probably to precompute the resulting string size, allocate manually the result, then fill it in (using std::string::operator +=).

That said, I would just write into std::ostringstream and take the result at the end (but YMMV).

Sign up to request clarification or add additional context in comments.

4 Comments

The benchmark in the duplicate seems to indicate otherwise. Do you have data to justify your claim?
@rici, actually, the data in the duplicate indicates what I said: The most efficient solution is probably to precompute the resulting string size, allocate manually the result, then fill it in (using std::string::operator +=).
I meant the claim that string stream are linked lists of buffers.
@rici I don't see anything in the standard having any requirement on how the data is stored for a stringstream. I assume the best performer varies by implementation

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.