stringstreamfmt

Why is libfmt slower than stringstream append?


I have a codebase that uses business logic to convert csv files to xml-like config files. This code uses stringstreams heavily to construct the config files some of which has inline SQL statements in them. I was looking to refactor parts of this code and decided to use libfmt to construct the config strings. The code is definitely more readable compared the stringstreams but I was also hoping to have had a significant performance bump.

However, I was testing a simple benchmark of libfmt against other ways to construct a string and I find it consistently slow even compared to stringstreams. (Although the above test also includes the std::format (mostly out of curiosity), we haven't moved to C++20 yet and so cannot use it.)

Why is this the case and what can I do to improve it?

I have looked through the following related question but my use case is different. Why is {fmt} slower than std::stringstream?

My benchmark code I tried, is available here: https://godbolt.org/z/xrhPdarqa


Solution

  • godbolt is not suitable for benchmarks like this for multiple reasons, including the fact that it uses debug versions of {fmt} and other libraries. So you are effectively comparing a debug version of {fmt} with an optimized version of sstream. You even get a warning from Google Benchmark itself:

    ***WARNING*** Library was built as DEBUG. Timings may be affected.
    

    A partial workaround is to use the header-only mode which shows that {fmt} is 2.5-3x faster than sstream in this case (https://godbolt.org/z/WY4d3h9vr):

    --------------------------------------------------------------------
    Benchmark                          Time             CPU   Iterations
    --------------------------------------------------------------------
    BM_test_string_append            146 ns         82.2 ns      7974239
    BM_test_sstream_append           674 ns          344 ns      1465041
    BM_test_fmt_string_append        273 ns          125 ns      6728817
    BM_test_std_format_append        415 ns          223 ns      2596699