PrevUpHomeNext

The Bigger Picture

The presented conversion-related performance data (and potential performance-related concerns) have to be taken in perspective. A special project with serious high performance requirements is most likely to require special solutions which are most likely to cast out many generic libraries. Still, the existence of such projects did not kill or diminish in any way the importance of generic libraries. And Boost.Convert is one such generic library.

More so, if performance is a concern, then, in all likelihood, for the great majority of the mainstream projects Boost.Convert will be far from the top on the performance profiler's list. For example, to measure conversion-related overhead relative to std::string-related overhead, std::string was replaced with a custom small-string type:

struct my_string
{
    using      this_type = my_string;
    using     value_type = char;
    using       iterator = value_type*;
    using const_iterator = value_type const*;

    my_string ();
    my_string (const_iterator, const_iterator =0);

    char const*    c_str () const { return storage_; }
    const_iterator begin () const { return storage_; }
    const_iterator   end () const { return storage_ + strlen(storage_); }
    this_type& operator= (char const*);

    private:

    static size_t const size_ = 12;
    char storage_[size_];
};

The class above is essentially a glorified 12-bytes character buffer sufficient to accommodate string representations of 32-bit integers. Deployed with the same converters and the same algorithms:

printf("strtol int-to std::string/small-string: %.2f/%.2f seconds.\n",
       local::to_str<std::string, int>(boost::cnv::strtol()),
       local::to_str<  my_string, int>(boost::cnv::strtol()));
printf("spirit int-to std::string/small-string: %.2f/%.2f seconds.\n",
       local::to_str<std::string, int>(boost::cnv::spirit()),
       local::to_str<  my_string, int>(boost::cnv::spirit()));
printf("stream int-to std::string/small-string: %.2f/%.2f seconds.\n",
       local::to_str<std::string, int>(boost::cnv::cstream()),
       local::to_str<  my_string, int>(boost::cnv::cstream()));
printf("charconv int-to std::string/small-string: %.2f/%.2f seconds.\n",
       local::to_str<std::string, int>(boost::cnv::charconv()),
       local::to_str<  my_string, int>(boost::cnv::charconv()));

It produced the following relative results (compiled with gcc -O3):

gcc-4.6.3 (no std::string small-string optimization)
strtol int-to std::string/small-string: 1.41/0.53 seconds.
spirit int-to std::string/small-string: 1.98/1.04 seconds.
stream int-to std::string/small-string: 2.49/1.40 seconds.

gcc-11.2.0 (with std::string small-string optimization)
strtol   int-to std::string/small-string: 0.29/0.27 seconds.
spirit   int-to std::string/small-string: 0.37/0.37 seconds.
stream   int-to std::string/small-string: 0.67/0.61 seconds.
charconv int-to std::string/small-string: 0.28/0.28 seconds.

The results suggest that for the projects that deal with string-related conversions and routinely deploy std::string facilities the conversion-related overhead will be outweighed by the overhead of std::string memory management related operations.


PrevUpHomeNext