Вложенные функции через lambda
От: tdiff  
Дата: 27.08.14 12:19
Оценка:
Если я хочу объявить внутри функцию, вложенную в другую, можно поступить примерно вот так:


void f()
{
  auto g = [] (int x) { return x > 0; };

  // use g somehow
  ...
}



Но правильно ли я понмиаю, что каждый раз, заходя в f, будет создан новый объект lambda_xxx и это теоретически должно снижать производительность?

Есть ли смысл заменить auto g на static auto g?

Может компилятор такие лямбды без захвата оптимизирует и превращает в свободные функции?

Или использовать лямбды без захвата — баловство и надо вынести g() из f()?
a
Re: Вложенные функции через lambda
От: watchmaker  
Дата: 27.08.14 12:33
Оценка:
Здравствуйте, tdiff, Вы писали:



T>Но правильно ли я понмиаю, что каждый раз, заходя в f, будет создан новый объект lambda_xxx и это теоретически должно снижать производительность?

Всё что там можно создавать — создаётся ещё при компиляции. Или что по твоему может содержаться в объекте lambda_xxx?

T>Есть ли смысл заменить auto g на static auto g?

Нет.

T>Может компилятор такие лямбды без захвата оптимизирует и превращает в свободные функции?

Да они по-сути и и есть свободные функции. Тут даже включать оптимизацию не нужно. То есть за все компиляторы утверждать не буду, но в clang/gcc с этим всё хорошо — никаких накладных расходов лямбды без захвата не вносят.
Re: Вложенные функции через lambda
От: Кодт Россия  
Дата: 27.08.14 12:34
Оценка: 1 (1)
Здравствуйте, tdiff, Вы писали:

T>Но правильно ли я понмиаю, что каждый раз, заходя в f, будет создан новый объект lambda_xxx и это теоретически должно снижать производительность?


Нет.
Конкретно в этом случае у лямбды нет связанных переменных, поэтому она реализуется через обычную, хотя и анонимную, функцию, а переменная g — это, попросту, указатель на функцию.

Если же связанные переменные есть, то получается объект анонимного класса, чьи поля суть значения переменных (заголовок [=] ) или ссылка на кадр стека (заголовок [&] ), и у которого есть метод — operator().
Чем больше переменных захватывается по значению, тем толще объект и тем больше накладные расходы.

T>Есть ли смысл заменить auto g на static auto g?


Практически, нет.
Пока переменная g не меняется после инициализации, это всё равно, что константа.
А поскольку она указывает на одну и ту же анонимную функцию (мы же just-in-time компиляцию не практикуем?), там константа времени компиляции.

T>Может компилятор такие лямбды без захвата оптимизирует и превращает в свободные функции?


Именно это он и делает.
Перекуём баги на фичи!
Re: Вложенные функции через lambda
От: jazzer Россия Skype: enerjazzer
Дата: 27.08.14 12:40
Оценка: 2 (1)
Здравствуйте, tdiff, Вы писали:

T>Может компилятор такие лямбды без захвата оптимизирует и превращает в свободные функции?


Да, это прописано явно в стандарте [expr.prim.lambda].6:

The closure type for a non-generic lambda-expression with no lambda-capture has a public non-virtual nonexplicit
const conversion function to pointer to function with C++ language linkage (7.5) having the same
parameter and return types as the closure type’s function call operator.
...

auto glambda = [](auto a) { return a; };
int (*fp)(int) = glambda;

jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: Вложенные функции через lambda
От: tdiff  
Дата: 27.08.14 13:02
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Да, это прописано явно в стандарте [expr.prim.lambda].6:


Спасибо, надо было самому пойти прочесть внимательно.
Re[2]: Вложенные функции через lambda
От: uzhas Ниоткуда  
Дата: 27.08.14 13:09
Оценка: +1
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, tdiff, Вы писали:


T>>Может компилятор такие лямбды без захвата оптимизирует и превращает в свободные функции?


J>Да, это прописано явно в стандарте [expr.prim.lambda].6:


тут вообще-то сказано о другом, а именно о возможности скастить к функции, то есть получить некий указатель, через который можно запустить лямбду
оптимизатор оперирует другими категориями все же

по поводу оптимизатора: профилируйте
Re[3]: Вложенные функции через lambda
От: jazzer Россия Skype: enerjazzer
Дата: 27.08.14 16:27
Оценка:
Здравствуйте, uzhas, Вы писали:

T>>>Может компилятор такие лямбды без захвата оптимизирует и превращает в свободные функции?


J>>Да, это прописано явно в стандарте [expr.prim.lambda].6:


U>тут вообще-то сказано о другом, а именно о возможности скастить к функции, то есть получить некий указатель, через который можно запустить лямбду

U>оптимизатор оперирует другими категориями все же

U>по поводу оптимизатора: профилируйте


Это понятно все, речь все же о том, что если бы там было нечто шибко сложное, то это невозможно было бы привести к указателю на функцию. А раз это получается по сути простая функция — все обычные оптимизации для нее уже давно имеются.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: Вложенные функции через lambda
От: zaufi Земля  
Дата: 28.08.14 18:31
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, uzhas, Вы писали:


T>>>>Может компилятор такие лямбды без захвата оптимизирует и превращает в свободные функции?


J>>>Да, это прописано явно в стандарте [expr.prim.lambda].6:


U>>тут вообще-то сказано о другом, а именно о возможности скастить к функции, то есть получить некий указатель, через который можно запустить лямбду

U>>оптимизатор оперирует другими категориями все же

U>>по поводу оптимизатора: профилируйте


J>Это понятно все, речь все же о том, что если бы там было нечто шибко сложное, то это невозможно было бы привести к указателю на функцию. А раз это получается по сути простая функция — все обычные оптимизации для нее уже давно имеются.


вплоть до того, что тело ламбды, даже с capture list, может быть заинлайнено по месту... например в алгоритме std::for_each -- в результате чего в машинных командах его не отличить от "обычного" цикла написанного руками
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.