«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Почему лямбды более оптимизируемы, чем простые функции в C++?

Почему лямбды более оптимизируемы, чем простые функции в C++?

Опубликовано 16 ноября 2024 г.
Просматривать:999

Why are Lambdas More Optimizable than Plain Functions in C  ?

Почему лямбды допускают расширенную оптимизацию компилятора по сравнению с обычными функциями

Стандартная библиотека C (второе издание) Николая Джосуттиса утверждает, что лямбды могут более эффективно оптимизироваться компиляторами по сравнению с простыми функциями. Это преимущество проистекает из природы лямбда-выражений как функциональных объектов.

Когда лямбда-выражение передается в шаблон функции, оно создается как новая функция, специально адаптированная для этого объекта. Это позволяет компилятору легко встроить лямбда-вызов. И наоборот, в случае простых функций указатель функции передается в шаблон функции. Традиционно компиляторы сталкивались с трудностями при встраивании вызовов, выполняемых через указатели функций.

Чтобы проиллюстрировать эту концепцию, рассмотрим следующий шаблон функции:

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

Вызов этой функции с помощью лямбды:

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

результат создания экземпляра, созданного компилятором:

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

В этом случае компилятор имеет доступ к _some_lambda_type::operator() и может легко встраивать к нему вызовы. Каждая лямбда имеет отдельный тип, поэтому использование другой лямбды с помощью функции map() приведет к созданию нового экземпляра.

Однако, если бы вместо этого использовался указатель на функцию:

map(int* begin, int* end, int (*f)(int)) {
    for (; begin != end;   begin)
        *begin = f(*begin);
}

Компилятор не сможет встроить вызовы f до тех пор, пока не будет встроен также охватывающий вызов Map(), что позволит ему точно определить конкретную функцию. Это подчеркивает преимущество лямбда-выражений перед простыми функциями с точки зрения оптимизации компилятора.

Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3