• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2<html>
3<head>
4<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5<title>Practical considerations</title>
6<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
7<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
8<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
9<link rel="up" href="../lambda.html" title="Chapter 20. Boost.Lambda">
10<link rel="prev" href="extending.html" title="Extending return type deduction system">
11<link rel="next" href="s08.html" title="Relation to other Boost libraries">
12</head>
13<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
14<table cellpadding="2" width="100%"><tr>
15<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
16<td align="center"><a href="../../../index.html">Home</a></td>
17<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
18<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
19<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
20<td align="center"><a href="../../../more/index.htm">More</a></td>
21</tr></table>
22<hr>
23<div class="spirit-nav">
24<a accesskey="p" href="extending.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../lambda.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="s08.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
25</div>
26<div class="section">
27<div class="titlepage"><div><div><h2 class="title" style="clear: both">
28<a name="id-1.3.21.9"></a>Practical considerations</h2></div></div></div>
29<div class="toc"><dl class="toc">
30<dt><span class="section"><a href="s07.html#id-1.3.21.9.2">Performance</a></span></dt>
31<dt><span class="section"><a href="s07.html#id-1.3.21.9.3">About compiling</a></span></dt>
32<dt><span class="section"><a href="s07.html#id-1.3.21.9.4">Portability</a></span></dt>
33</dl></div>
34<div class="section">
35<div class="titlepage"><div><div><h3 class="title">
36<a name="id-1.3.21.9.2"></a>Performance</h3></div></div></div>
37<p>In theory, all overhead of using STL algorithms and lambda functors
38compared to hand written loops can be optimized away, just as the overhead
39from standard STL function objects and binders can.
40
41Depending on the compiler, this can also be true in practice.
42We ran two tests with the GCC 3.0.4 compiler on 1.5 GHz Intel Pentium 4.
43The optimization flag -03 was used.
44</p>
45<p>
46In the first test we compared lambda functors against explicitly written
47function objects.
48We used both of these styles to define unary functions which multiply the
49argument repeatedly by itself.
50We started with the identity function, going up to
51x<sup>5</sup>.
52The expressions were called inside a <code class="literal">std::transform</code> loop,
53reading the argument from one <code class="literal">std::vector&lt;int&gt;</code>
54and placing the result into another.
55The length of the vectors was 100 elements.
56The running times are listed in
57<a class="xref" href="s07.html#table:increasing_arithmetic_test" title="Table 20.3. Test 1">Table 20.3, “Test 1”</a>.
58
59We can observe that there is no significant difference between the
60two approaches.
61</p>
62<p>
63In the second test we again used <code class="literal">std::transform</code> to
64perform an operation to each element in a 100-element long vector.
65This time the element type of the vectors was <code class="literal">double</code>
66and we started with very simple arithmetic expressions and moved to
67more complex ones.
68The running times are listed in <a class="xref" href="s07.html#table:ll_vs_stl_test" title="Table 20.4. Test 2">Table 20.4, “Test 2”</a>.
69
70Here, we also included classic STL style unnamed functions into tests.
71We do not show these expressions, as they get rather complex.
72For example, the
73last expression in <a class="xref" href="s07.html#table:ll_vs_stl_test" title="Table 20.4. Test 2">Table 20.4, “Test 2”</a> written with
74classic STL tools contains 7 calls to <code class="literal">compose2</code>,
758 calls to <code class="literal">bind1st</code>
76and altogether 14 constructor invocations for creating
77<code class="literal">multiplies</code>, <code class="literal">minus</code>
78and <code class="literal">plus</code> objects.
79
80In this test the BLL expressions are a little slower (roughly 10% on average,
81less than 14% in all cases)
82than the corresponding hand-written function objects.
83The performance hit is a bit greater with classic STL expressions,
84up to 27% for the simplest expressios.
85</p>
86<p>
87The tests suggest that the BLL does not introduce a loss of performance
88compared to STL function objects.
89With a reasonable optimizing compiler, one should expect the performance characteristics be comparable to using classic STL.
90Moreover, with simple expressions the performance can be expected to be close
91to that of explicitly written function objects.
92
93
94
95Note however, that evaluating a lambda functor consist of a sequence of calls to small functions that are declared inline.
96If the compiler fails to actually expand these functions inline,
97the performance can suffer.
98The running time can more than double if this happens.
99Although the above tests do not include such an expression, we have experienced
100this for some seemingly simple expressions.
101
102
103</p>
104<div class="table">
105<a name="table:increasing_arithmetic_test"></a><p class="title"><b>Table 20.3. Test 1</b></p>
106<div class="table-contents">
107<div class="caption">CPU time of expressions with integer multiplication written as a lambda expression and as a traditional hand-coded function object class.
108The running times are expressed in arbitrary units.</div>
109<table class="table" summary="Test 1">
110<colgroup>
111<col>
112<col>
113<col>
114</colgroup>
115<thead><tr>
116<th>expression</th>
117<th>lambda expression</th>
118<th>hand-coded function object</th>
119</tr></thead>
120<tbody>
121<tr>
122<td>x</td>
123<td>240</td>
124<td>230</td>
125</tr>
126<tr>
127<td>x*x</td>
128<td>340</td>
129<td>350</td>
130</tr>
131<tr>
132<td>x*x*x</td>
133<td>770</td>
134<td>760</td>
135</tr>
136<tr>
137<td>x*x*x*x</td>
138<td>1180</td>
139<td>1210</td>
140</tr>
141<tr>
142<td>x*x*x*x*x</td>
143<td>1950</td>
144<td>1910</td>
145</tr>
146</tbody>
147</table>
148</div>
149</div>
150<p><br class="table-break">
151</p>
152<p>
153</p>
154<div class="table">
155<a name="table:ll_vs_stl_test"></a><p class="title"><b>Table 20.4. Test 2</b></p>
156<div class="table-contents">
157<div class="caption">CPU time of arithmetic expressions written as lambda
158expressions, as classic STL unnamed functions (using <code class="literal">compose2</code>, <code class="literal">bind1st</code> etc.) and as traditional hand-coded function object classes.
159Using BLL terminology,
160<code class="literal">a</code> and <code class="literal">b</code> are bound arguments in the expressions, and <code class="literal">x</code> is open.
161All variables were of types <code class="literal">double</code>.
162The running times are expressed in arbitrary units.</div>
163<table class="table" summary="Test 2">
164<colgroup>
165<col>
166<col>
167<col>
168<col>
169</colgroup>
170<thead><tr>
171<th>expression</th>
172<th>lambda expression</th>
173<th>classic STL expression</th>
174<th>hand-coded function object</th>
175</tr></thead>
176<tbody>
177<tr>
178<td>ax</td>
179<td>330</td>
180<td>370</td>
181<td>290</td>
182</tr>
183<tr>
184<td>-ax</td>
185<td>350</td>
186<td>370</td>
187<td>310</td>
188</tr>
189<tr>
190<td>ax-(a+x)</td>
191<td>470</td>
192<td>500</td>
193<td>420</td>
194</tr>
195<tr>
196<td>(ax-(a+x))(a+x)</td>
197<td>620</td>
198<td>670</td>
199<td>600</td>
200</tr>
201<tr>
202<td>((ax) - (a+x))(bx - (b+x))(ax - (b+x))(bx - (a+x))</td>
203<td>1660</td>
204<td>1660</td>
205<td>1460</td>
206</tr>
207</tbody>
208</table>
209</div>
210</div>
211<p><br class="table-break">
212</p>
213<p>Some additional performance testing with an earlier version of the
214library is described
215<a class="xref" href="../lambda.html#cit:jarvi:00" title="The Lambda Library : Lambda Abstraction in C++">[<abbr class="abbrev">Jär00</abbr>]</a>.
216</p>
217</div>
218<div class="section">
219<div class="titlepage"><div><div><h3 class="title">
220<a name="id-1.3.21.9.3"></a>About compiling</h3></div></div></div>
221<p>The BLL uses templates rather heavily, performing numerous recursive instantiations of the same templates.
222This has (at least) three implications:
223</p>
224<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
225<li class="listitem"><p>
226While it is possible to write incredibly complex lambda expressions, it probably isn't a good idea.
227Compiling such expressions may end up requiring a lot of memory
228at compile time, and being slow to compile.
229</p></li>
230<li class="listitem"><p>
231The types of lambda functors that result from even the simplest lambda expressions are cryptic.
232Usually the programmer doesn't need to deal with the lambda functor types at all, but in the case of an error in a lambda expression, the compiler usually outputs the types of the lambda functors involved.
233This can make the error messages very long and difficult to interpret, particularly if the compiler outputs the whole chain of template instantiations.
234</p></li>
235<li class="listitem"><p>
236The C++ Standard suggests a template nesting level of 17 to help detect infinite recursion.
237Complex lambda templates can easily exceed this limit.
238Most compilers allow a greater number of nested templates, but commonly require the limit explicitly increased with a command line argument.
239</p></li>
240</ul></div>
241</div>
242<div class="section">
243<div class="titlepage"><div><div><h3 class="title">
244<a name="id-1.3.21.9.4"></a>Portability</h3></div></div></div>
245<div class="toc"><dl class="toc"><dt><span class="section"><a href="s07.html#id-1.3.21.9.4.3">Test coverage</a></span></dt></dl></div>
246<p>
247The BLL works with the following compilers, that is, the compilers are capable of compiling the test cases that are included with the BLL:
248
249      </p>
250<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
251<li class="listitem">GCC 3.0.4
252	</li>
253<li class="listitem">KCC 4.0f with EDG 2.43.1
254	</li>
255<li class="listitem">GCC 2.96 (fails with one test case, the <code class="filename">exception_test.cpp</code> results in an internal compiler error.
256)
257
258	</li>
259</ul></div>
260<p>
261</p>
262<div class="section">
263<div class="titlepage"><div><div><h4 class="title">
264<a name="id-1.3.21.9.4.3"></a>Test coverage</h4></div></div></div>
265<p>The following list describes the test files included and the features that each file covers:
266
267</p>
268<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
269<li class="listitem"><p>
270<code class="filename">bind_tests_simple.cpp</code> : Bind expressions of different arities and types of target functions: function pointers, function objects and member functions.
271Function composition with bind expressions.</p></li>
272<li class="listitem"><p><code class="filename">bind_tests_simple_function_references.cpp</code> :
273Repeats all tests from <code class="filename">bind_tests_simple.cpp</code> where the target function is a function pointer, but uses function references instead.
274</p></li>
275<li class="listitem"><p><code class="filename">bind_tests_advanced.cpp</code> : Contains tests for nested bind expressions, <code class="literal">unlambda</code>, <code class="literal">protect</code>, <code class="literal">const_parameters</code> and <code class="literal">break_const</code>.
276Tests passing lambda functors as actual arguments to other lambda functors, currying, and using the <code class="literal">sig</code> template to specify the return type of a function object.
277</p></li>
278<li class="listitem"><p>
279<code class="filename">operator_tests_simple.cpp</code> :
280Tests using all operators that are overloaded for lambda expressions, that is, unary and binary arithmetic,
281bitwise,
282comparison,
283logical,
284increment and decrement,
285compound,
286assignment,
287subscrict,
288address of,
289dereference, and comma operators.
290The streaming nature of shift operators is tested, as well as pointer arithmetic with plus and minus operators.
291</p></li>
292<li class="listitem"><p><code class="filename">member_pointer_test.cpp</code> : The pointer to member operator is complex enough to warrant a separate test file.
293</p></li>
294<li class="listitem"><p>
295<code class="filename">control_structures.cpp</code> :
296Tests for the looping and if constructs.
297</p></li>
298<li class="listitem"><p>
299<code class="filename">switch_construct.cpp</code> :
300Includes tests for all supported arities of the switch statement, both with and without the default case.
301</p></li>
302<li class="listitem"><p>
303<code class="filename">exception_test.cpp</code> :
304Includes tests for throwing exceptions and for try/catch constructs with varying number of catch blocks.
305</p></li>
306<li class="listitem"><p>
307<code class="filename">constructor_tests.cpp</code> :
308Contains tests for <code class="literal">constructor</code>, <code class="literal">destructor</code>, <code class="literal">new_ptr</code>, <code class="literal">delete_ptr</code>, <code class="literal">new_array</code> and <code class="literal">delete_array</code>.
309</p></li>
310<li class="listitem"><p>
311<code class="filename">cast_test.cpp</code> : Tests for the four cast expressions, as well as <code class="filename">typeid</code> and <code class="literal">sizeof</code>.
312</p></li>
313<li class="listitem"><p>
314<code class="filename">extending_return_type_traits.cpp</code> : Tests extending the return type deduction system for user defined types.
315Contains several user defined operators and the corresponding specializations for the return type deduction templates.
316</p></li>
317<li class="listitem"><p>
318<code class="filename">is_instance_of_test.cpp</code> : Includes tests for an internally used traits template, which can detect whether a given type is an instance of a certain template or not.
319</p></li>
320<li class="listitem"><p>
321<code class="filename">bll_and_function.cpp</code> :
322Contains tests for using <code class="literal">boost::function</code> together with lambda functors.
323</p></li>
324</ul></div>
325<p>
326
327</p>
328</div>
329</div>
330</div>
331<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
332<td align="left"></td>
333<td align="right"><div class="copyright-footer">Copyright © 1999-2004 Jaakko Järvi, Gary Powell<p>Use, modification and distribution is subject to the Boost
334    Software License, Version 1.0. (See accompanying file
335    <code class="filename">LICENSE_1_0.txt</code> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)</p>
336</div></td>
337</tr></table>
338<hr>
339<div class="spirit-nav">
340<a accesskey="p" href="extending.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../lambda.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="s08.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
341</div>
342</body>
343</html>
344