Лямбда-оптимизация и встроенные функции: преимущество компилятора
Утверждение Николая Джосуттиса о том, что лямбда-выражения демонстрируют превосходную оптимизацию компилятора по сравнению с простыми функциями, заинтриговало многих разработчики. Исследуя это утверждение, мы стремимся раскрыть основные причины этого преимущества оптимизации.
Функциональные объекты и встраивание
Лямбды, будучи функциональными объектами, обладают ключевым преимуществом: передача их в Шаблоны функций запускают создание экземпляра специальной функции специально для этой лямбды. Это позволяет компилятору без особых усилий встроить лямбда-вызов.
Напротив, функции используют указатели на функции при передаче в шаблоны функций. Традиционно компиляторы сталкиваются с проблемами при встраивании вызовов через указатели на функции. Встроенная оптимизация возможна только в том случае, если сама объемлющая функция встроена.
Экземпляры шаблонов: исследование различий
Чтобы проиллюстрировать это несоответствие, рассмотрим шаблон функции карты:
templatevoid 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() и может напрямую встраивать к ней вызовы. Каждый отдельный тип лямбды вызывает новый экземпляр карты, гарантируя оптимизацию для конкретной лямбды.
Напротив, вызов карты с указателем на функцию приводит к следующему экземпляру:
template void map(int* begin, int* end, int (*f)(int)) { for (; begin != end; begin) *begin = f(*begin); }
Здесь указатель функции f указывает на разные адреса для каждого вызова карты, что запрещает встроенную оптимизацию. Вызов Map должен быть встроен, чтобы компилятор мог преобразовать f в конкретную функцию.
Таким образом, особенность лямбда-выражений как функциональных объектов и их способность облегчать создание экземпляров шаблонов предоставляют компиляторам большие возможности оптимизации, чем вызовы традиционных функций. через указатели.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3