Home  >  Article  >  Backend Development  >  Can Lambdas Be Optimized Better Than Plain Functions By Compilers?

Can Lambdas Be Optimized Better Than Plain Functions By Compilers?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-11-19 18:33:03204browse

Can Lambdas Be Optimized Better Than Plain Functions By Compilers?

Compiler Optimizations for Lambdas vs. Plain Functions

In his book, "The C Standard Library (Second Edition)," Nicolai Josuttis claims that lambdas can be optimized better by the compiler than plain functions. This may seem counterintuitive, given that both lambdas and plain functions can be inlined. However, there is a subtle difference between the two that allows for better optimizations in the case of lambdas.

The Difference: Function Objects vs. Function Pointers

Lambdas are function objects, while plain functions are essentially function pointers. When passing a lambda to a function template, a new function specifically for that object is instantiated. This allows the compiler to trivially inline the lambda call.

In contrast, passing a plain function to a function template results in a function pointer being passed. Compilers have historically struggled with inlining calls via function pointers. While they can theoretically be inlined, it only occurs if the surrounding function is also inlined.

An Example

Consider the following function template:

template <typename Iter, typename F>
void map(Iter begin, Iter end, F f) {
    for (; begin != end; ++begin)
        *begin = f(*begin);
}

Calling it with a lambda:

int a[] = { 1, 2, 3, 4 };
map(begin(a), end(a), [](int n) { return n * 2; });

Will result in a unique instantiation:

template <>
void map<int*, _some_lambda_type>(int* begin, int* end, _some_lambda_type f) {
    for (; begin != end; ++begin)
        *begin = f.operator()(*begin);
}

The compiler can identify the lambda's operator() and trivially inline calls to it.

But when called with a function pointer:

map(begin(a), end(a), &multiply_by_two);

The instantiation becomes:

template <>
void map<int*, int (*)(int)>(int* begin, int* end, int (*f)(int)) {
    for (; begin != end; ++begin)
        *begin = f(*begin);
}

Here, f references different functions each time map is called, preventing the compiler from inlining calls unless map itself is inlined.

Conclusion

The unique type of lambdas as function objects enables compilers to create specific function instantiations and seamlessly inline their calls. This enhanced optimization capability distinguishes lambdas from plain functions, making them a preferred choice for improving code performance and efficiency.

The above is the detailed content of Can Lambdas Be Optimized Better Than Plain Functions By Compilers?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn