2021-10-05 21:37:46 +02:00

140 lines
17 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Performance</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="Chapter 1. Boost.Convert 2.0">
<link rel="up" href="../index.html" title="Chapter 1. Boost.Convert 2.0">
<link rel="prev" href="algorithms.html" title="Boost.Convert with Standard Algorithms">
<link rel="next" href="performance/boost_convert_overhead.html" title="Boost.Convert Overhead">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="algorithms.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="performance/boost_convert_overhead.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_convert.performance"></a><a class="link" href="performance.html" title="Performance">Performance</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="performance.html#boost_convert.performance.converters_compared">Converters
Compared</a></span></dt>
<dt><span class="section"><a href="performance/boost_convert_overhead.html">Boost.Convert
Overhead</a></span></dt>
<dt><span class="section"><a href="performance/the_bigger_picture.html">The Bigger
Picture</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_convert.performance.converters_compared"></a><a class="link" href="performance.html#boost_convert.performance.converters_compared" title="Converters Compared">Converters
Compared</a>
</h3></div></div></div>
<p>
The performance of <span class="emphasis"><em>Boost.Convert</em></span> 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.
</p>
<p>
In turn, the performance of every particular converter depends on the platform,
the compiler used and the particular implementation of the underlying conversion
component (<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">stream</span></code>, <code class="computeroutput"><span class="identifier">printf</span></code>,
<span class="emphasis"><em>Boost.Spirit</em></span>, etc.). Consequently, the results below
are only an approximate indication of <span class="emphasis"><em>relative</em></span> performance
of the mentioned converters on the tested platforms.
</p>
<p>
When compiled with gcc-5.4.0 on 64-bit Ubuntu 16.04, tests produced the following
results:
</p>
<pre class="programlisting"><span class="identifier">str</span><span class="special">-</span><span class="identifier">to</span><span class="special">-</span><span class="keyword">int</span><span class="special">:</span> <span class="identifier">spirit</span><span class="special">/</span><span class="identifier">strtol</span><span class="special">/</span><span class="identifier">lcast</span><span class="special">/</span><span class="identifier">scanf</span><span class="special">/</span><span class="identifier">stream</span><span class="special">=</span> <span class="number">0.27</span><span class="special">/</span> <span class="number">0.35</span><span class="special">/</span> <span class="number">0.92</span><span class="special">/</span> <span class="number">2.11</span><span class="special">/</span> <span class="number">2.09</span> <span class="identifier">seconds</span><span class="special">.</span>
<span class="identifier">str</span><span class="special">-</span><span class="identifier">to</span><span class="special">-</span><span class="identifier">lng</span><span class="special">:</span> <span class="identifier">spirit</span><span class="special">/</span><span class="identifier">strtol</span><span class="special">/</span><span class="identifier">lcast</span><span class="special">/</span><span class="identifier">scanf</span><span class="special">/</span><span class="identifier">stream</span><span class="special">=</span> <span class="number">0.69</span><span class="special">/</span> <span class="number">0.31</span><span class="special">/</span> <span class="number">1.28</span><span class="special">/</span> <span class="number">2.07</span><span class="special">/</span> <span class="number">2.50</span> <span class="identifier">seconds</span><span class="special">.</span>
<span class="identifier">str</span><span class="special">-</span><span class="identifier">to</span><span class="special">-</span><span class="identifier">dbl</span><span class="special">:</span> <span class="identifier">spirit</span><span class="special">/</span><span class="identifier">strtol</span><span class="special">/</span><span class="identifier">lcast</span><span class="special">/</span><span class="identifier">scanf</span><span class="special">/</span><span class="identifier">stream</span><span class="special">=</span> <span class="number">0.73</span><span class="special">/</span> <span class="number">1.06</span><span class="special">/</span> <span class="number">7.95</span><span class="special">/</span> <span class="number">2.87</span><span class="special">/</span> <span class="number">5.10</span> <span class="identifier">seconds</span><span class="special">.</span>
<span class="keyword">int</span><span class="special">-</span><span class="identifier">to</span><span class="special">-</span><span class="identifier">str</span><span class="special">:</span> <span class="identifier">spirit</span><span class="special">/</span><span class="identifier">strtol</span><span class="special">/</span><span class="identifier">lcast</span><span class="special">/</span><span class="identifier">prntf</span><span class="special">/</span><span class="identifier">stream</span><span class="special">=</span> <span class="number">1.96</span><span class="special">/</span> <span class="number">1.39</span><span class="special">/</span> <span class="number">2.52</span><span class="special">/</span> <span class="number">3.49</span><span class="special">/</span> <span class="number">2.58</span> <span class="identifier">seconds</span><span class="special">.</span>
<span class="identifier">lng</span><span class="special">-</span><span class="identifier">to</span><span class="special">-</span><span class="identifier">str</span><span class="special">:</span> <span class="identifier">spirit</span><span class="special">/</span><span class="identifier">strtol</span><span class="special">/</span><span class="identifier">lcast</span><span class="special">/</span><span class="identifier">prntf</span><span class="special">/</span><span class="identifier">stream</span><span class="special">=</span> <span class="number">2.45</span><span class="special">/</span> <span class="number">1.51</span><span class="special">/</span> <span class="number">2.32</span><span class="special">/</span> <span class="number">3.30</span><span class="special">/</span> <span class="number">2.63</span> <span class="identifier">seconds</span><span class="special">.</span>
<span class="identifier">dbl</span><span class="special">-</span><span class="identifier">to</span><span class="special">-</span><span class="identifier">str</span><span class="special">:</span> <span class="identifier">spirit</span><span class="special">/</span><span class="identifier">strtol</span><span class="special">/</span><span class="identifier">lcast</span><span class="special">/</span><span class="identifier">prntf</span><span class="special">/</span><span class="identifier">stream</span><span class="special">=</span> <span class="number">6.62</span><span class="special">/</span> <span class="number">4.46</span><span class="special">/</span> <span class="number">28.69</span><span class="special">/</span> <span class="number">20.60</span><span class="special">/</span> <span class="number">14.16</span> <span class="identifier">seconds</span><span class="special">.</span>
</pre>
<p>
Based on the results, all things considered, I tend to conclude that there
is no clear winner:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
the <span class="emphasis"><em>Spirit.Qi</em></span>-based converter was the fastest for
string to basic (<code class="computeroutput"><span class="keyword">int</span></code>, <code class="computeroutput"><span class="keyword">double</span></code>) conversions. So, it might be a
good candidate for the tasks predominantly doing that kind of conversions
(with <span class="emphasis"><em>Spirit.Qi</em></span> conversion-related limitations in
mind); <span class="emphasis"><em>Spirit.Karma</em></span>'s <span class="emphasis"><em>to-string</em></span>
performance did not seem as impressive;
</li>
<li class="listitem">
the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">iostream</span></code>-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;
</li>
<li class="listitem">
the <code class="computeroutput"><span class="identifier">strtol</span></code>-inspired converter
was reasonably fast and with formatting support might be an attractive
all-rounder. It should be noted that it is nowhere as mature as <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">cnv</span><span class="special">::</span><span class="identifier">lexical_cast</span></code> or <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">cnv</span><span class="special">::</span><span class="identifier">stream</span></code>.
So, bugs are to be expected.
</li>
</ul></div>
<p>
For user-defined types <code class="computeroutput"><span class="identifier">cnv</span><span class="special">::</span><span class="identifier">lexical_cast</span></code>,
<code class="computeroutput"><span class="identifier">cnv</span><span class="special">::</span><span class="identifier">cstream</span></code> and <code class="computeroutput"><span class="identifier">cnv</span><span class="special">::</span><span class="identifier">strtol</span></code>
were tested with the following results:
</p>
<pre class="programlisting"><span class="identifier">str</span><span class="special">-</span><span class="identifier">to</span><span class="special">-</span><span class="identifier">user</span><span class="special">-</span><span class="identifier">type</span><span class="special">:</span> <span class="identifier">lcast</span><span class="special">/</span><span class="identifier">stream</span><span class="special">/</span><span class="identifier">strtol</span><span class="special">=</span><span class="number">0.36</span><span class="special">/</span><span class="number">0.18</span><span class="special">/</span><span class="number">0.07</span> <span class="identifier">seconds</span><span class="special">.</span>
<span class="identifier">user</span><span class="special">-</span><span class="identifier">type</span><span class="special">-</span><span class="identifier">to</span><span class="special">-</span><span class="identifier">str</span><span class="special">:</span> <span class="identifier">lcast</span><span class="special">/</span><span class="identifier">stream</span><span class="special">/</span><span class="identifier">strtol</span><span class="special">=</span><span class="number">0.58</span><span class="special">/</span><span class="number">0.09</span><span class="special">/</span><span class="number">0.06</span> <span class="identifier">seconds</span><span class="special">.</span>
</pre>
<p>
To provide <span class="emphasis"><em>string-to-user-type</em></span> and <span class="emphasis"><em>user-type-to-string</em></span>
conversions the first two deploy the same standard <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">iostream</span></code>
library. However, <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">cnv</span><span class="special">::</span><span class="identifier">cstream</span></code>
considerably outperforms <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">lexical_cast</span></code>
in these tests. The results reflect different underlying designs. Namely,
the standard <span class="emphasis"><em>Boost.Convert</em></span> deployment pattern is to
create a converter or converters once and then re-use them. <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">lexical_cast</span></code>, on the other hand, creates
and then destroys a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">stream</span></code> instance every time the function
is called and the <a href="http://www.boost.org/doc/libs/1_55_0/doc/html/boost_lexical_cast/performance.html" target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">lexical_cast</span></code> performance</a> table
indicates that the "std::stringstream <span class="emphasis"><em>with construction</em></span>"
operation is considerably more expensive compared to "std::stringstream
<span class="emphasis"><em>without construction</em></span>".
</p>
<p>
<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">cnv</span><span class="special">::</span><span class="identifier">strtol</span></code>
support for user types has been implemented similarly but without the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">stream</span></code>-related
overhead. That resulted in the best out-of-three performance results.
</p>
<p>
Based on the performance data, I tend to conclude that, given type-safety
and benefits provided by the <span class="emphasis"><em>Boost.Convert</em></span> framework,
it (with appropriate converters) should probably be the first choice for
conversion-related tasks.
</p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2009-2020 Vladimir Batov<p>
Distributed under the Boost Software License, Version 1.0. See copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>.
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="algorithms.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="performance/boost_convert_overhead.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>