2

I would like to increase the amount of std::string data which is allocated on the stack. By default should be 16 bytes, I'd like more something like 32 bytes. What I am not sure is how to proceed: are the default 16 bytes part of the default allocator, so that changing the allocator would be enough? Or would it be faster to use something like boost::small_vector?

nyarlathotep108
  • 5,275
  • 2
  • 26
  • 64
  • Do you mean something like `std::string.resize()`? – skratchi.at Sep 24 '19 at 07:25
  • @skratchi.at no, resize() is a runtime thing that also `std::vector` has. What I mean is that default compile time reseved space which is allocated on the stack which is peculiar to `std::string`. Dynamic allocation happens only when this stack portion of memory is full. – nyarlathotep108 Sep 24 '19 at 07:28
  • 5
    I think you are talking about the [Short String Optimization](https://stackoverflow.com/q/21694302/1171191)? That is not guaranteed nor exposed by The Standard, and implementations of `std::string` that I am aware of do not give you any control over that. – BoBTFish Sep 24 '19 at 07:30
  • 3
    Your best option is to do your own string. – LeDYoM Sep 24 '19 at 07:30
  • @nyarlathotep108 Ok, I see. This would lead me to some questions. Why is that a problem? Why would you want to change that? What is the result you hope for? This sounds to me like premature optimization. – skratchi.at Sep 24 '19 at 07:39
  • 1
    The optimisation is implemented by storing the data in a part of the object. Expanding this would increase the size of every `std::string` object. – molbdnilo Sep 24 '19 at 07:45
  • The "on the stack" part is problematic. In particular, it points to a skills discrepancy. If you have the skills to implement SSO properly, you would use proper terminology. – MSalters Sep 24 '19 at 11:38

2 Answers2

3

Short-string optimisation is just that, an optimisation. It's not covered by the standard at all, which means it's up to individual standard library implementations whether they use it and whether they expose any control over it. Consult your standard library's documentation. Be aware that using that would make your code non-portable.

I am not aware of any standard library implementation which exposes any control over this feature.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • AllocatoAware classes are the exposure of allocation method. This really should be a comment – Swift - Friday Pie Sep 24 '19 at 07:32
  • @Swift-FridayPie The allocator only comes into play when the string implementation has exhausted its SSO space (if any). Or are you aware of a way in which a model of the `Allocator` concept can reuse the *stack space of the container itself* (which is what the question is asking about)? – Angew is no longer proud of SO Sep 24 '19 at 07:38
  • It's possible, by creating instance of custom allocator, aware of target string,and string on stack sadly, reusing wouldn't be portable because it relies on knowledge of storage structure. And you can't store more data than target container provides. – Swift - Friday Pie Sep 24 '19 at 07:49
  • by providing it address as a state,. That's definitely leads to an UB, but SSO itself usually implemented through ways which are deemed UB by ISO standard. They work only on platform and compiler \component implementation they are meant for. Much less hassle is to provide external statically allocated storage, if you want to trade stack space for heap fragmentation. – Swift - Friday Pie Sep 24 '19 at 08:17
  • 1
    @Swift-FridayPie: There's no real need for UB with SSO. Even C++98 had `union`. – MSalters Sep 24 '19 at 11:41
2

It depends which standards you want to support. Prior to C++11 allocators were stateless. After C++11 an instance of supplied allocator object is stored within allocator-aware class and controls its replacement. The problem , is that the object itself isn't stored in automatic storage or, at least, not limited to such type of storage.

Because each implementation of std::basic_string got different size and usable area (e.g. gcc implementation - only 16 bytes, i.e 15 + trailing zero, clang 22 bytes, etc.) and you can't change library class, to actually use custom SSO, you likely have to provide storage on stack manually and create class-adapter around std::basic_string.

Swift - Friday Pie
  • 12,777
  • 2
  • 19
  • 42
  • IIRC, prior to C++11 implementations could (at their choice) support stateful allocators. This meant that portable code could not rely on it, but the implementation itself could. – MSalters Sep 24 '19 at 11:36