boost/libs/convert/doc/html/boost_convert/performance.html
2022-12-15 23:45:23 +08:00

140 lines
17 KiB
HTML

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<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&#160;1.&#160;Boost.Convert 2.0">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;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 &#169; 2009-2016 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>