What is short/small string optimization? It’s a way to squeeze some bytes into a std::string object without actually allocating them on the heap. It’s a hackery involving C++ unions and clever space management. Say sizeof(std::string) is, oh I don’t know, 24 bytes on Mac’s LLVM? The implementation manages to squeeze 22 characters into that (not including the terminating NULL) before having to allocate on the heap. Impressive. Less impressive is GCC’s implementation on Linux, with sizeof(std::string) being 32 bytes but only 15 can be optimized before going to the heap. I used to have this number for Visual Studio’s implementation but… see the rant above šŸ˜› The capacity of an empty string is the give away for how much you can fit in it before going to the heap šŸ˜‰

Check it out yourself on your favorite compiler with the code below!

sso.cpp:

sizeof  : 24
Capacity: 22
Small   : 22
Big     : 31

Program output (LLVM on Mac).

4 Replies to “SSO of std::string”

  1. The llvm implementation must rely on the alignment of pointers returned from malloc, so they can just use the lowest bits as flags. Clever.

  2. (for the 100$ :P) => Use conan as package manager

    I’ve already tried to build your examples on windows but unfortannely not all required packages are available

    So you need to create the missing packages and then you can do simple the following for all systems (linux, windows, mac..etc):
    1) install conan client: pip install conan
    2) cd && mkdir build && cd build
    3) conan install ..
    4) conan build ..

    I can send you my example… but don’t know where to send to, but the conanfile.py will something like:

    from conans import ConanFile, CMake, tools
    from conans.tools import os_info
    import os
    import sys
    import shutil

    class BlogConan(ConanFile):
    settings = “os”, “compiler”, “build_type”, “arch”, “cppstd”
    generators = “cmake_paths”
    options = {“shared”: [True, False]}
    default_options = {“shared”: False}
    requires = (
    “TBB/4.4.4@conan/stable”,
    “range-v3/0.4.0@ericniebler/stable”,
    “boost/1.69.0@conan/stable”,
    “protobuf/3.6.1@bincrafters/stable”,
    “mysql-connector-c/6.1.11@bincrafters/stable”,
    “Catch2/2.7.0@catchorg/stable”,
    “lz4/1.8.3@bincrafters/stable”,
    “libcurl/7.61.1@bincrafters/stable”,
    “fmt/5.3.0@bincrafters/stable”,
    “cryptopp/7.0.0@bincrafters/stable”,
    “botan/2.9.0@bincrafters/stable”
    )
    # if using conan to build then use the same cmake for packages
    def build_requirements(self):
    self.build_requires(“cmake_installer/3.13.0@conan/stable”)

    For any doubt please ask
    Nuno

Leave a Reply