Feature request: make every String a smartstring

I would note that prior experience with std::string (C++) is not all rosy. There are performance issues with the optimizers having trouble optimizing out the branches for reads/writes due to the indirection, issues that do not occur for more straightforward types.

This is sufficient, as far as I am concerned, to avoid using such a "clever" trick as the default representation, and instead aim at offering a parameterizable implementation of String which can be declined in multiple formats:

  • InlineString<N>: len in 0..=N, cap = N.
  • SmallString<N>: originally inline if len <= N, then heap-allocated.
  • String: regular, default, heap-allocated.

Then people can choose what makes sense for their own usecase, and do not need to pay for fancy features they do not use.


Disclaimer: I am biased.

The idea of declining collections in such a way is what has motivated me to work on the Store API RFC.

The obvious follow-ups of the RFC would be the "Store-ification" of the standard library collection types: Box, Vec, String, etc... and putting them in core.

This, in itself, is not enough to have a truly compact small string. Just swapping out the pointer + allocator of Vec for a handle + store allow defining an InlineVec<N> or SmallVec<N>, but those still retain the two usize fields for len and cap. However, since nobody depends on core::Vec and core::String today since they do not exist, merely defining them -- unstably, at first -- would open the possibility of adding more parameterization to the types, such as defining Length and Capacity traits, or any other combination.

The re-exports made by the alloc or collection crates can then take care of exposing an API matching the current one, for example: pub type String = core::String<usize, usize, Global>;.

5 Likes