1

I have to construct a string by concatenating a few other strings. I also know the maximum size of the string, and I want to reserve the capacity so there are no reallocations. My code right now looks something like this:

#include <string>
using std::string;

// Setup
...

string a,b,c;

// Strings are filled with relevant data
...

string msg;
msg.reserve(200);
msg = "A=";  msg += a; msg += ',';
msg += "B="; msg += b; msg += ',';
msg += "C="; msg += c; msg += '.';

I previously used stringstream for this, but performance was twice as slow. Is there a way to reserve the string capacity at construction, instead of having to allocate memory twice? Also is there a better (faster) way of appending the strings?

9
  • This code won't allocate twice. The default constructor doesn't allocate any memory. Commented Jun 1, 2017 at 9:48
  • @SebastianRedl The object itself must live somewhere in memory. I thought that the memory for the actual string is contiguous with the memory of the object if it was possible to reserve at construction Commented Jun 1, 2017 at 9:52
  • @EyalK. I don't see anything like that in cplusplus.com/reference/string/string/string Commented Jun 1, 2017 at 9:58
  • @SebastianRedl std::string tends to allocate some memory even for default construction. wandbox.org/permlink/n7uQ4kdra2KW6G4P Commented Jun 1, 2017 at 9:58
  • @EyalK. : in your example the objects have automatic storage and common implementation will use the stack for them, while the actual string memory has dynamic storage and common implementations put them into the heap. So having the memory for the actual string contiguous with the memory of the object is quite uncommon... Commented Jun 1, 2017 at 9:59

1 Answer 1

2

Is there a way to reserve the string capacity at construction instead of having to allocate memory twice?

There is no "allocating memory twice" here. You correctly create a string then ask it to reserve some memory. Other than reserving a more accurate amount (rather than just guessing 200), you're fine.

Technically, an implementation is allowed to start off with an unspecified capacity, but it's likely that you're seeing the results of small-string optimisation (a statically-allocated buffer inside the std::string itself, to avoid dynamic allocations in some cases) rather than this feature being used.

If you're really concerned about it, you could instantiate the string with 200 \0 characters, then erase them all; then its underlying capacity will be consistent.

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

10 Comments

Alright, thanks. What about the way I'm constructing the string? I feel like there must be some more efficient way to do it (I need to push out these messages as fast as possible)
@EyalK.: Don't worry about it. Finish your program then benchmark this function and see whether you need to improve it. But you probably don't.
This function is not in a tight loop, but it does participate in a sort of "race" against rival messages. It will not show up in profiling, but it does need to be as fast as possible to win the race
@EyalK. then redesign your program so you don't have a data race?
@EyalK.: It is likely that this has no observable affect on the results of the race. It's very very very fast, much faster than network I/O functions. Profile before you spend more time micro-optimising.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.