c++ - Why can lambdas be better optimized by the compiler than plain functions? -
in book the c++ standard library (second edition) nicolai josuttis states lambdas can better optimized compiler plain functions.
in addition, c++ compilers optimize lambdas better ordinary functions. (page 213)
why that?
i thought when comes inlining there shouldn't difference more. reason think of compilers might have better local context lambdas , such can make more assumptions , perform more optimizations.
the reason lambdas function objects passing them function template instantiate new function object. compiler can trivially inline lambda call.
for functions, on other hand, old caveat applies: function pointer gets passed function template, , compilers traditionally have lot of problems inlining calls via function pointers. can theoretically inlined, if surrounding function inlined well.
as example, consider following function template:
template <typename iter, typename f> void map(iter begin, iter end, f f) { (; begin != end; ++begin) *begin = f(*begin); } calling lambda this:
int a[] = { 1, 2, 3, 4 }; map(begin(a), end(a), [](int n) { return n * 2; }); results in instantiation (created compiler):
template <> void map<int*, _some_lambda_type>(int* begin, int* end, _some_lambda_type f) { (; begin != end; ++begin) *begin = f.operator()(*begin); } … compiler knows _some_lambda_type::operator () , can inline calls trivially. (and invoking function map any other lambda create new instantiation of map since each lambda has distinct type.)
but when called function pointer, instantiation looks follows:
template <> void map<int*, int (*)(int)>(int* begin, int* end, int (*f)(int)) { (; begin != end; ++begin) *begin = f(*begin); } … , here f points different address each call map , compiler cannot inline calls f unless surrounding call map has been inlined compiler can resolve f 1 specific function.
Comments
Post a Comment