Reputation: 4211
Before I begin, I need to state that my application uses lots of strings, which are on average quite small, and which do not change once created.
In Visual Studio 2010, I noticed that the capacity of std::string is at least 30. Even if I write std::string str = "test";
, the capacity of str is 30. The function str.shrink_to_fit()
does nothing about this although a function with the same name exists for std::vector and works as expected, namely decreasing the capacity so that capacity == size.
std::string::shrink_to_fit()
not work at expected?Upvotes: 7
Views: 2400
Reputation: 4010
What you observe is a result of SSO (short string optimization), as pointed out by others.
What you could do about it depends on the usage pattern:
If you strings are parts of one big string, which is typical for parsing, you can use classes like std::experimental::string_view
, GSL string_span
, Google's StringPiece, LLVM's StringRef etc. which do not store data themselves but only refer to a piece of some other string, while providing interface similar to std::string
.
If there are multiple copies of the same strings (especially long ones), it may make sense to use CoW (copy-on-write) strings, where copies share the same buffer using reference counter mechanism until modified. (But be aware of downsides)
If the strings are very short (just a few chars) it may make sense to write your own specialized class, something in line with Handling short codes by Andrzej
Whatever case you chose, it is important to establish good benchmarking procedure to clearly see what effect (if any) you get.
Upd: after rereading the introduction to the question, I think the third approach is the best for you.
Upvotes: 1
Reputation: 1444
If you are using a lot of small strings in your application then you might want to take a look at fbstring (https://github.com/facebook/folly/blob/master/folly/docs/FBString.md).
Upvotes: 0
Reputation: 180415
One reason that std::string::shrink_to_fit()
does nothing is that it is not required to by the standard
Remarks: shrink_to_fit is a non-binding request to reduce
capacity()
tosize()
. [ Note: The request is non-binding to allow latitude for implementation-specific optimizations. —end note ]
If you want to make sure the string shrinks then you can use the swap()
trick like
std::string(string_to_shrink).swap(string_to_shrink)
Another reason this may not work is that the implementer of std::string
is allowed to implement short string optimization so you could always have a minimum size of 30 on your implementation.
Upvotes: 1
Reputation: 59811
std::string
implementation most likely uses some form of the short string optimization resulting in a fixed size for smaller strings and no effect for shrink_to_fit
. Note that shrink_to_fit
is non-binding for the implementation, so this is actually conforming.vector<char>
to get more precise memory management, but would loose some of the additional functionality of std::string
. You could also write your own string
wrapper which uses a vector
internally.Upvotes: 8