11

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?

Community
  • 1
  • 1
Spacemoose
  • 3,856
  • 1
  • 27
  • 48
  • 4
    Here is a newer question http://stackoverflow.com/questions/18892281/most-optimized-way-of-concatenation-in-strings 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. – eerorika Jun 23 '15 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. – rwong Oct 19 '16 at 17:51

1 Answers1

10

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).

utnapistim
  • 26,809
  • 3
  • 46
  • 82
  • The benchmark in the duplicate seems to indicate otherwise. Do you have data to justify your claim? – rici Jun 23 '15 at 16:11
  • @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 +=)._ – utnapistim Jun 23 '15 at 18:29
  • 1
    I meant the claim that string stream are linked lists of buffers. – rici Jun 23 '15 at 18:56