performance_considerations.html 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
  4. <title>Performance considerations</title>
  5. <link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
  6. <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
  7. <link rel="home" href="../../index.html" title="Boost.Optional">
  8. <link rel="up" href="../../optional/tutorial.html" title="Tutorial">
  9. <link rel="prev" href="type_requirements.html" title="Type requirements">
  10. <link rel="next" href="../../optional/reference.html" title="Reference">
  11. </head>
  12. <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
  13. <table cellpadding="2" width="100%"><tr>
  14. <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
  15. <td align="center"><a href="../../../../../../index.html">Home</a></td>
  16. <td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
  17. <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
  18. <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
  19. <td align="center"><a href="../../../../../../more/index.htm">More</a></td>
  20. </tr></table>
  21. <hr>
  22. <div class="spirit-nav">
  23. <a accesskey="p" href="type_requirements.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.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="../../optional/reference.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
  24. </div>
  25. <div class="section">
  26. <div class="titlepage"><div><div><h3 class="title">
  27. <a name="boost_optional.tutorial.performance_considerations"></a><a class="link" href="performance_considerations.html" title="Performance considerations">Performance
  28. considerations</a>
  29. </h3></div></div></div>
  30. <p>
  31. Technical details aside, the memory layout of <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
  32. for a generic <code class="computeroutput"><span class="identifier">T</span></code> is more-less
  33. this:
  34. </p>
  35. <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
  36. <span class="keyword">class</span> <span class="identifier">optional</span>
  37. <span class="special">{</span>
  38. <span class="keyword">bool</span> <span class="identifier">_initialized</span><span class="special">;</span>
  39. <span class="identifier">std</span><span class="special">::</span><span class="identifier">aligned_storage_t</span><span class="special">&lt;</span><span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">t</span><span class="special">),</span> <span class="keyword">alignof</span><span class="special">(</span><span class="identifier">T</span><span class="special">)&gt;</span> <span class="identifier">_storage</span><span class="special">;</span>
  40. <span class="special">};</span>
  41. </pre>
  42. <p>
  43. Lifetime of the <code class="computeroutput"><span class="identifier">T</span></code> inside
  44. <code class="computeroutput"><span class="identifier">_storage</span></code> is manually controlled
  45. with placement-<code class="computeroutput"><span class="keyword">new</span></code>s and pseudo-destructor
  46. calls. However, for scalar <code class="computeroutput"><span class="identifier">T</span></code>s
  47. we use a different way of storage, by simply holding a <code class="computeroutput"><span class="identifier">T</span></code>:
  48. </p>
  49. <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
  50. <span class="keyword">class</span> <span class="identifier">optional</span>
  51. <span class="special">{</span>
  52. <span class="keyword">bool</span> <span class="identifier">_initialized</span><span class="special">;</span>
  53. <span class="identifier">T</span> <span class="identifier">_storage</span><span class="special">;</span>
  54. <span class="special">};</span>
  55. </pre>
  56. <p>
  57. We call it a <span class="emphasis"><em>direct</em></span> storage. This makes <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> a
  58. trivially-copyable type for scalar <code class="computeroutput"><span class="identifier">T</span></code>s.
  59. This only works for compilers that support defaulted functions (including
  60. defaulted move assignment and constructor). On compilers without defaulted
  61. functions we still use the direct storage, but <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
  62. is no longer recognized as trivially-copyable. Apart from scalar types, we
  63. leave the programmer a way of customizing her type, so that it is reconized
  64. by <code class="computeroutput"><span class="identifier">optional</span></code> as candidate
  65. for optimized storage, by specializing type trait <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">opitonal_config</span><span class="special">::</span><span class="identifier">optional_uses_direct_storage_for</span></code>:
  66. </p>
  67. <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">X</span> <span class="comment">// not trivial</span>
  68. <span class="special">{</span>
  69. <span class="identifier">X</span><span class="special">()</span> <span class="special">{}</span>
  70. <span class="special">};</span>
  71. <span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">optional_config</span> <span class="special">{</span>
  72. <span class="keyword">template</span> <span class="special">&lt;&gt;</span> <span class="keyword">struct</span> <span class="identifier">optional_uses_direct_storage_for</span><span class="special">&lt;</span><span class="identifier">X</span><span class="special">&gt;</span> <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">true_type</span> <span class="special">{};</span>
  73. <span class="special">}}</span>
  74. </pre>
  75. <h5>
  76. <a name="boost_optional.tutorial.performance_considerations.h0"></a>
  77. <span class="phrase"><a name="boost_optional.tutorial.performance_considerations.controlling_the_size"></a></span><a class="link" href="performance_considerations.html#boost_optional.tutorial.performance_considerations.controlling_the_size">Controlling
  78. the size</a>
  79. </h5>
  80. <p>
  81. For the purpose of the following analysis, considering memory layouts, we
  82. can think of it as:
  83. </p>
  84. <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
  85. <span class="keyword">class</span> <span class="identifier">optional</span>
  86. <span class="special">{</span>
  87. <span class="keyword">bool</span> <span class="identifier">_initialized</span><span class="special">;</span>
  88. <span class="identifier">T</span> <span class="identifier">_storage</span><span class="special">;</span>
  89. <span class="special">};</span>
  90. </pre>
  91. <p>
  92. Given type <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span></code>, and
  93. assuming that <code class="computeroutput"><span class="keyword">sizeof</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span> <span class="special">==</span>
  94. <span class="number">4</span></code>, we will get <code class="computeroutput"><span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;)</span>
  95. <span class="special">==</span> <span class="number">8</span></code>.
  96. This is so because of the alignment rules, for our two members we get the
  97. following alignment:
  98. </p>
  99. <p>
  100. <span class="inlinemediaobject"><img src="../../images/opt_align1.png" alt="opt_align1"></span>
  101. </p>
  102. <p>
  103. This means you can fit twice as many <code class="computeroutput"><span class="keyword">int</span></code>s
  104. as <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span></code>s into
  105. the same space of memory. Therefore, if the size of the objects is critical
  106. for your application (e.g., because you want to utilize your CPU cache in
  107. order to gain performance) and you have determined you are willing to trade
  108. the code clarity, it is recommended that you simply go with type <code class="computeroutput"><span class="keyword">int</span></code> and use some 'magic value' to represent
  109. <span class="emphasis"><em>not-an-int</em></span>, or use something like <a href="https://github.com/akrzemi1/markable" target="_top"><code class="computeroutput"><span class="identifier">markable</span></code></a> library.
  110. </p>
  111. <p>
  112. Even if you cannot spare any value of <code class="computeroutput"><span class="keyword">int</span></code>
  113. to represent <span class="emphasis"><em>not-an-int</em></span> (e.g., because every value is
  114. useful, or you do want to signal <span class="emphasis"><em>not-an-int</em></span> explicitly),
  115. at least for <code class="computeroutput"><span class="identifier">Trivial</span></code> types
  116. you should consider storing the value and the <code class="computeroutput"><span class="keyword">bool</span></code>
  117. flag representing the <span class="emphasis"><em>null-state</em></span> separately. Consider
  118. the following class:
  119. </p>
  120. <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Record</span>
  121. <span class="special">{</span>
  122. <span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">_min</span><span class="special">;</span>
  123. <span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">_max</span><span class="special">;</span>
  124. <span class="special">};</span>
  125. </pre>
  126. <p>
  127. Its memory layout can be depicted as follows:
  128. </p>
  129. <p>
  130. <span class="inlinemediaobject"><img src="../../images/opt_align2.png" alt="opt_align2"></span>
  131. </p>
  132. <p>
  133. This is exactly the same as if we had the following members:
  134. </p>
  135. <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Record</span>
  136. <span class="special">{</span>
  137. <span class="keyword">bool</span> <span class="identifier">_has_min</span><span class="special">;</span>
  138. <span class="keyword">int</span> <span class="identifier">_min</span><span class="special">;</span>
  139. <span class="keyword">bool</span> <span class="identifier">_has_max</span><span class="special">;</span>
  140. <span class="keyword">int</span> <span class="identifier">_max</span><span class="special">;</span>
  141. <span class="special">};</span>
  142. </pre>
  143. <p>
  144. But when they are stored separately, we at least have an option to reorder
  145. them like this:
  146. </p>
  147. <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Record</span>
  148. <span class="special">{</span>
  149. <span class="keyword">bool</span> <span class="identifier">_has_min</span><span class="special">;</span>
  150. <span class="keyword">bool</span> <span class="identifier">_has_max</span><span class="special">;</span>
  151. <span class="keyword">int</span> <span class="identifier">_min</span><span class="special">;</span>
  152. <span class="keyword">int</span> <span class="identifier">_max</span><span class="special">;</span>
  153. <span class="special">};</span>
  154. </pre>
  155. <p>
  156. Which gives us the following layout (and smaller total size):
  157. </p>
  158. <p>
  159. <span class="inlinemediaobject"><img src="../../images/opt_align3.png" alt="opt_align3"></span>
  160. </p>
  161. <p>
  162. Sometimes it requires detailed consideration what data we make optional.
  163. In our case above, if we determine that both minimum and maximum value can
  164. be provided or not provided together, but one is never provided without the
  165. other, we can make only one optional memebr:
  166. </p>
  167. <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Limits</span>
  168. <span class="special">{</span>
  169. <span class="keyword">int</span> <span class="identifier">_min</span><span class="special">;</span>
  170. <span class="keyword">int</span> <span class="identifier">_max</span><span class="special">;</span>
  171. <span class="special">};</span>
  172. <span class="keyword">struct</span> <span class="identifier">Record</span>
  173. <span class="special">{</span>
  174. <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">Limits</span><span class="special">&gt;</span> <span class="identifier">_limits</span><span class="special">;</span>
  175. <span class="special">};</span>
  176. </pre>
  177. <p>
  178. This would give us the following layout:
  179. </p>
  180. <p>
  181. <span class="inlinemediaobject"><img src="../../images/opt_align4.png" alt="opt_align4"></span>
  182. </p>
  183. <h5>
  184. <a name="boost_optional.tutorial.performance_considerations.h1"></a>
  185. <span class="phrase"><a name="boost_optional.tutorial.performance_considerations.optional_function_parameters"></a></span><a class="link" href="performance_considerations.html#boost_optional.tutorial.performance_considerations.optional_function_parameters">Optional
  186. function parameters</a>
  187. </h5>
  188. <p>
  189. Having function parameters of type <code class="computeroutput"><span class="keyword">const</span>
  190. <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span></code>
  191. may incur certain unexpected run-time cost connected to copy construction
  192. of <code class="computeroutput"><span class="identifier">T</span></code>. Consider the following
  193. code.
  194. </p>
  195. <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">fun</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">Big</span><span class="special">&gt;&amp;</span> <span class="identifier">v</span><span class="special">)</span>
  196. <span class="special">{</span>
  197. <span class="keyword">if</span> <span class="special">(</span><span class="identifier">v</span><span class="special">)</span> <span class="identifier">doSomethingWith</span><span class="special">(*</span><span class="identifier">v</span><span class="special">);</span>
  198. <span class="keyword">else</span> <span class="identifier">doSomethingElse</span><span class="special">();</span>
  199. <span class="special">}</span>
  200. <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
  201. <span class="special">{</span>
  202. <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">Big</span><span class="special">&gt;</span> <span class="identifier">ov</span><span class="special">;</span>
  203. <span class="identifier">Big</span> <span class="identifier">v</span><span class="special">;</span>
  204. <span class="identifier">fun</span><span class="special">(</span><span class="identifier">none</span><span class="special">);</span>
  205. <span class="identifier">fun</span><span class="special">(</span><span class="identifier">ov</span><span class="special">);</span> <span class="comment">// no copy</span>
  206. <span class="identifier">fun</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span> <span class="comment">// copy constructor of Big</span>
  207. <span class="special">}</span>
  208. </pre>
  209. <p>
  210. No copy elision or move semantics can save us from copying type <code class="computeroutput"><span class="identifier">Big</span></code> here. Not that we need any copy, but
  211. this is how <code class="computeroutput"><span class="identifier">optional</span></code> works.
  212. In order to avoid copying in this case, one could provide second overload
  213. of <code class="computeroutput"><span class="identifier">fun</span></code>:
  214. </p>
  215. <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">fun</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Big</span><span class="special">&amp;</span> <span class="identifier">v</span><span class="special">)</span>
  216. <span class="special">{</span>
  217. <span class="identifier">doSomethingWith</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span>
  218. <span class="special">}</span>
  219. <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
  220. <span class="special">{</span>
  221. <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">Big</span><span class="special">&gt;</span> <span class="identifier">ov</span><span class="special">;</span>
  222. <span class="identifier">Big</span> <span class="identifier">v</span><span class="special">;</span>
  223. <span class="identifier">fun</span><span class="special">(</span><span class="identifier">ov</span><span class="special">);</span> <span class="comment">// no copy</span>
  224. <span class="identifier">fun</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span> <span class="comment">// no copy: second overload selected</span>
  225. <span class="special">}</span>
  226. </pre>
  227. <p>
  228. Alternatively, you could consider using an optional reference instead:
  229. </p>
  230. <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">fun</span><span class="special">(</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="identifier">Big</span><span class="special">&amp;&gt;</span> <span class="identifier">v</span><span class="special">)</span> <span class="comment">// note where the reference is</span>
  231. <span class="special">{</span>
  232. <span class="keyword">if</span> <span class="special">(</span><span class="identifier">v</span><span class="special">)</span> <span class="identifier">doSomethingWith</span><span class="special">(*</span><span class="identifier">v</span><span class="special">);</span>
  233. <span class="keyword">else</span> <span class="identifier">doSomethingElse</span><span class="special">();</span>
  234. <span class="special">}</span>
  235. <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
  236. <span class="special">{</span>
  237. <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">Big</span><span class="special">&gt;</span> <span class="identifier">ov</span><span class="special">;</span>
  238. <span class="identifier">Big</span> <span class="identifier">v</span><span class="special">;</span>
  239. <span class="identifier">fun</span><span class="special">(</span><span class="identifier">none</span><span class="special">);</span>
  240. <span class="identifier">fun</span><span class="special">(</span><span class="identifier">ov</span><span class="special">);</span> <span class="comment">// doesn't compile</span>
  241. <span class="identifier">fun</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span> <span class="comment">// no copy</span>
  242. <span class="special">}</span>
  243. </pre>
  244. </div>
  245. <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
  246. <td align="left"></td>
  247. <td align="right"><div class="copyright-footer">Copyright &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014-2018 Andrzej Krzemie&#324;ski<p>
  248. Distributed under the Boost Software License, Version 1.0. (See accompanying
  249. file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
  250. </p>
  251. </div></td>
  252. </tr></table>
  253. <hr>
  254. <div class="spirit-nav">
  255. <a accesskey="p" href="type_requirements.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.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="../../optional/reference.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
  256. </div>
  257. </body>
  258. </html>