Gnollrunner said:
If you are using C++ std::string probably already has SSO. Make sure this is really your problem. If you are passing stings around by value you will make a copy every time. Pass by reference where appropriate. I typically dislike std::sting for my usage since if you don't need SSO, you end up wasting a lot of memory. I mostly prefer COW strings which also alleviates the copy problem if you are lazy about passing by reference. Finally if stings are really a killer for you, you can also make a specialized heap that's optimized for them.
See, I've been wondering the same thing. There are many places where IMHO SSO is actually a pessimisation in modern code. Consider this example:
class Foo
{
Foo(std::string&& strName) noexcept :
strName(std::move(strName)) {}
private:
std::string strName;
};
using FooStorage = std::unordered_map<std::string, Foo>;
FooStorage mFoos;
std::wstring strName = /*...*/;
mFoos.try_emplace(strName, std::move(strName));
I have many cases where an objects primary storage is in a map by its own name. Now, its not really optimal having a second std::wstring in the map, so in c++20 we could do:
using FooStorage = std::unordered_map<std::string_view, Foo>;
FooStorage mFoos;
std::wstring strName = /*...*/;
mFoos.try_emplace(strName, std::move(strName));
which IMHO is vastly superior in this case. However, since std::string uses SSO, we really cannot do this, since the data-storage of strName for a small string changed while the string is being passed into “Foo”. For cases where the element is stored by std::unique_ptr or similar, we can work around this by using the actual member-variable to construct the key - but if the element is stored directly in the map, there is not way to achieve this.
So its good to see that I'm not the only one who is at least a bit wary of SSO. (Hopefully this reply is still on-topic enough; otherwise I might make a separate thread to discuss this topic).