]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/optional/doc/html/boost_optional/tutorial/performance_considerations.html
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / optional / doc / html / boost_optional / tutorial / performance_considerations.html
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.78.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 is more-less this:
33 </p>
34 <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>
35 <span class="keyword">class</span> <span class="identifier">optional</span>
36 <span class="special">{</span>
37 <span class="keyword">bool</span> <span class="identifier">_initialized</span><span class="special">;</span>
38 <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>
39 <span class="special">};</span>
40 </pre>
41 <p>
42 But for the purpose of this analysis, considering memory layouts, we can
43 think of it as:
44 </p>
45 <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>
46 <span class="keyword">class</span> <span class="identifier">optional</span>
47 <span class="special">{</span>
48 <span class="keyword">bool</span> <span class="identifier">_initialized</span><span class="special">;</span>
49 <span class="identifier">T</span> <span class="identifier">_storage</span><span class="special">;</span>
50 <span class="special">};</span>
51 </pre>
52 <p>
53 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
54 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>
55 <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>
56 <span class="special">==</span> <span class="number">8</span></code>.
57 This is so because of the alignment rules, for our two members we get the
58 following alignment:
59 </p>
60 <p>
61 <span class="inlinemediaobject"><img src="../../images/opt_align1.png" alt="opt_align1"></span>
62 </p>
63 <p>
64 This means you can fit twice as many <code class="computeroutput"><span class="keyword">int</span></code>s
65 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
66 the same space of memory. Therefore, if the size of the objects is critical
67 for your application (e.g., because you want to utilize your CPU cache in
68 order to gain performance) and you have determined you are willing to trade
69 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
70 <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.
71 </p>
72 <p>
73 Even if you cannot spare any value of <code class="computeroutput"><span class="keyword">int</span></code>
74 to represent <span class="emphasis"><em>not-an-int</em></span> (e.g., because every value is
75 useful, or you do want to signal <span class="emphasis"><em>not-an-int</em></span> explicitly),
76 at least for <code class="computeroutput"><span class="identifier">Trivial</span></code> types
77 you should consider storing the value and the <code class="computeroutput"><span class="keyword">bool</span></code>
78 flag representing the <span class="emphasis"><em>null-state</em></span> separately. Consider
79 the following class:
80 </p>
81 <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Record</span>
82 <span class="special">{</span>
83 <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>
84 <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>
85 <span class="special">};</span>
86 </pre>
87 <p>
88 Its memory layout can be depicted as follows:
89 </p>
90 <p>
91 <span class="inlinemediaobject"><img src="../../images/opt_align2.png" alt="opt_align2"></span>
92 </p>
93 <p>
94 This is exactly the same as if we had the following members:
95 </p>
96 <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Record</span>
97 <span class="special">{</span>
98 <span class="keyword">bool</span> <span class="identifier">_has_min</span><span class="special">;</span>
99 <span class="keyword">int</span> <span class="identifier">_min</span><span class="special">;</span>
100 <span class="keyword">bool</span> <span class="identifier">_has_max</span><span class="special">;</span>
101 <span class="keyword">int</span> <span class="identifier">_max</span><span class="special">;</span>
102 <span class="special">};</span>
103 </pre>
104 <p>
105 But when they are stored separately, we at least have an option to reorder
106 them like this:
107 </p>
108 <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Record</span>
109 <span class="special">{</span>
110 <span class="keyword">bool</span> <span class="identifier">_has_min</span><span class="special">;</span>
111 <span class="keyword">bool</span> <span class="identifier">_has_max</span><span class="special">;</span>
112 <span class="keyword">int</span> <span class="identifier">_min</span><span class="special">;</span>
113 <span class="keyword">int</span> <span class="identifier">_max</span><span class="special">;</span>
114 <span class="special">};</span>
115 </pre>
116 <p>
117 Which gives us the following layout (and smaller total size):
118 </p>
119 <p>
120 <span class="inlinemediaobject"><img src="../../images/opt_align3.png" alt="opt_align3"></span>
121 </p>
122 <p>
123 Sometimes it requires detailed consideration what data we make optional.
124 In our case above, if we determine that both minimum and maximum value can
125 be provided or not provided together, but one is never provided without the
126 other, we can make only one optional memebr:
127 </p>
128 <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Limits</span>
129 <span class="special">{</span>
130 <span class="keyword">int</span> <span class="identifier">_min</span><span class="special">;</span>
131 <span class="keyword">int</span> <span class="identifier">_max</span><span class="special">;</span>
132 <span class="special">};</span>
133
134 <span class="keyword">struct</span> <span class="identifier">Record</span>
135 <span class="special">{</span>
136 <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>
137 <span class="special">};</span>
138 </pre>
139 <p>
140 This would give us the following layout:
141 </p>
142 <p>
143 <span class="inlinemediaobject"><img src="../../images/opt_align4.png" alt="opt_align4"></span>
144 </p>
145 <h5>
146 <a name="boost_optional.tutorial.performance_considerations.h0"></a>
147 <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
148 function parameters</a>
149 </h5>
150 <p>
151 Having function parameters of type <code class="computeroutput"><span class="keyword">const</span>
152 <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span></code>
153 may incur certain unexpected run-time cost connected to copy construction
154 of <code class="computeroutput"><span class="identifier">T</span></code>. Consider the following
155 code.
156 </p>
157 <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>
158 <span class="special">{</span>
159 <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>
160 <span class="keyword">else</span> <span class="identifier">doSomethingElse</span><span class="special">();</span>
161 <span class="special">}</span>
162
163 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
164 <span class="special">{</span>
165 <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>
166 <span class="identifier">Big</span> <span class="identifier">v</span><span class="special">;</span>
167 <span class="identifier">fun</span><span class="special">(</span><span class="identifier">none</span><span class="special">);</span>
168 <span class="identifier">fun</span><span class="special">(</span><span class="identifier">ov</span><span class="special">);</span> <span class="comment">// no copy</span>
169 <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>
170 <span class="special">}</span>
171 </pre>
172 <p>
173 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
174 this is how <code class="computeroutput"><span class="identifier">optional</span></code> works.
175 In order to avoid copying in this case, one could provide second overload
176 of <code class="computeroutput"><span class="identifier">fun</span></code>:
177 </p>
178 <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>
179 <span class="special">{</span>
180 <span class="identifier">doSomethingWith</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span>
181 <span class="special">}</span>
182
183 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
184 <span class="special">{</span>
185 <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>
186 <span class="identifier">Big</span> <span class="identifier">v</span><span class="special">;</span>
187 <span class="identifier">fun</span><span class="special">(</span><span class="identifier">ov</span><span class="special">);</span> <span class="comment">// no copy</span>
188 <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>
189 <span class="special">}</span>
190 </pre>
191 <p>
192 Alternatively, you could consider using an optional reference instead:
193 </p>
194 <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>
195 <span class="special">{</span>
196 <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>
197 <span class="keyword">else</span> <span class="identifier">doSomethingElse</span><span class="special">();</span>
198 <span class="special">}</span>
199
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">// doesn't compile</span>
206 <span class="identifier">fun</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span> <span class="comment">// no copy</span>
207 <span class="special">}</span>
208 </pre>
209 </div>
210 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
211 <td align="left"></td>
212 <td align="right"><div class="copyright-footer">Copyright &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014-2016 Andrzej Krzemie&#324;ski<p>
213 Distributed under the Boost Software License, Version 1.0. (See accompanying
214 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>)
215 </p>
216 </div></td>
217 </tr></table>
218 <hr>
219 <div class="spirit-nav">
220 <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>
221 </div>
222 </body>
223 </html>