Boost C++ Libraries of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards



Converters Compared
Boost.Convert Overhead
The Bigger Picture

The performance of Boost.Convert depends entirely on the performance of the converter deployed. A few converters have been tested for string conversions to basic types and to a user-defined type.

In turn, the performance of every particular converter depends on the platform, the compiler used and the particular implementation of the underlying conversion components (small-string optimization, std::stream, printf, Boost.Spirit, etc.). Consequently, the results below are only an approximate indication of relative performance of the mentioned converters on the tested platforms.

When compiled with gcc-11.2.0 on 64-bit Ubuntu 22.04, tests produced the following results:

str-to-int: spirit/strtol/lcast/scanf/stream/charconv= 0.15/0.13/1.99/0.86/0.67/0.16 seconds.
str-to-lng: spirit/strtol/lcast/scanf/stream/charconv= 0.12/0.15/2.04/0.88/0.66/0.12 seconds.
str-to-dbl: spirit/strtol/lcast/scanf/stream/charconv= 0.15/0.53/5.12/1.06/1.68/0.19 seconds.
int-to-str: spirit/strtol/lcast/prntf/stream/charconv= 0.39/0.29/0.43/1.09/0.68/0.29 seconds.
lng-to-str: spirit/strtol/lcast/prntf/stream/charconv= 0.39/0.29/0.45/1.11/0.68/0.31 seconds.
dbl-to-str: spirit/strtol/lcast/prntf/stream/charconv= 1.12/1.17/7.34/5.05/4.65/1.07 seconds.

Based on the above, all things considered, I tend to conclude that:

  • the Spirit.Qi-based, strtol-inspired and charconv-based converters were the fastest for string to basic (int, double) conversions. So, they might be good candidates for the tasks doing that kind of conversions (with Spirit.Qi conversion-related limitations in mind);
  • the std::iostream-based converter was comparatively slow. Still, given its maturity, availability and formatting support, it might be an option to consider if conversion performance is not your primary concern;
  • the boost::lexical_cast-based converter was consistently and noticeably the slowest (due to its underlying design);
  • the charconv-based and the strtol-inspired converters were overall the fastest and with formatting support might be attractive all-rounders.

For user-defined types converters were tested with the following results:

str-to-user-type: lcast/stream/strtol/charconv=0.13/0.05/0.01/0.02 seconds.
user-type-to-str: lcast/stream/strtol/charconv=0.11/0.03/0.01/0.01 seconds.

To provide string-to-user-type and user-type-to-string conversions the first two deploy the same standard std::iostream library. Still, boost::cnv::cstream considerably outperforms boost::lexical_cast in these tests. That reflects different underlying designs. Namely, the standard Boost.Convert deployment pattern is to create a converter or converters once and then re-use them. boost::lexical_cast, on the other hand, creates and then destroys a std::stream instance every time the function is called and the boost::lexical_cast performance table indicates that the "std::stringstream with construction" operation is considerably more expensive compared to "std::stringstream without construction".

boost::cnv::strtol and boost::cnv::charconv support for user types has been implemented similarly but without the std::stream-related overhead. That resulted in considerably better performance results.

Based on the performance data, I tend to conclude that, given type-safety and benefits provided by the Boost.Convert framework, it (with appropriate converters) should probably be the first choice for conversion-related tasks.