random memes }

Building a better string class

For nearly thirty years I used a minimal C-with-classes style string class.

This started back in the early 1990s, when writing a block-mode terminal emulator for Windows (Win16). The standard C++ string class was not efficient, and this application did a lot of cyclic use of strings. I found that a minimal wrapper around standard C string functions, with a free list, radically more efficient.

After a bit more than a decade, revisited my old assumptions. Much had changed as applications were now on Win32 (then). CPUs and compilers had also advanced. But the standard C++ string class had not improved. My old choice was still valid.

Note the C++ applications I wrote back then were strictly single-threaded. There was simply not a need for multi-threading. (Keep in mind that almost all desktops and servers to that time had a only single CPU.)

A few years ago, had a notion for a thread-local lock-free string class. My first attempt had behavior I did not understand, and I lost interest.

Of late, I have been working through the LLM-programming learning curve, so asked an LLM to look at the prior attempt. Took a few iterations (filtering out the usual LLM noise) but ended up with measurements against a working string class.

Seems the standard C++ string class is now much more efficient. Not sure when exactly that happened, or why it took decades, but it is now time to revisit my old assumptions.

Seems I can still beat the standard C++ string class, least for my expected uses, but not by much. The first column of numbers is for std::string and the second is for my base_strings::string_local_o class.

==== Using simple samples
std::string    6.959 ns : base_strings::string_local_o    6.792 ns pick
std::string    0.931 ns : base_strings::string_local_o    4.046 ns instantiate
std::string   31.820 ns : base_strings::string_local_o   16.097 ns assign from (const char*)
std::string   19.539 ns : base_strings::string_local_o   15.172 ns assign from same
std::string    7.219 ns : base_strings::string_local_o    2.781 ns dispose

==== Using sample bucket
std::string    6.930 ns : base_strings::string_local_o    6.177 ns pick
std::string    1.021 ns : base_strings::string_local_o    3.901 ns instantiate
std::string   29.588 ns : base_strings::string_local_o   18.542 ns assign from (const char*)
std::string   22.125 ns : base_strings::string_local_o   16.509 ns assign from same
std::string    8.112 ns : base_strings::string_local_o    2.804 ns dispose

This is not enough to suggest that anyone abandon std::string. Source are on GitHub.