Можно ли встроить лямбда-выражение? - PullRequest
12 голосов
/ 22 июля 2010

Я хочу вставить лямбда-выражение, поскольку оно очень короткое по соображениям производительности.Возможно ли это?

Ответы [ 6 ]

16 голосов
/ 22 июля 2010

Ключевое слово inline фактически не приводит к встраиванию функций. Любой недавний компилятор будет принимать лучшие решения относительно встраивания, чем вы.

В случае короткой лямбды функция, вероятно, будет встроенной.

Если вы пытаетесь использовать ключевое слово inline с лямбдой, ответ - нет, вы не можете его использовать.

13 голосов
/ 22 июля 2010

Компилятор встроит его, если сможет.Например, в g ++ 4.5 с параметром -O2

#include <vector>
#include <algorithm>

int main () {
    std::vector<int> a(10);
    for (int i = 0; i < 10; ++ i) a[i] = i;

    asm ("Ltransform_begin: nop; nop; nop; nop; nop; nop; ");
    std::transform(a.begin(), a.end(), a.begin(), [] (int x) { return 2*x; });
    asm ("Lforeach_begin: nop; nop; nop; nop; nop; nop; ");
    std::for_each(a.begin(), a.end(), [] (int x) { printf("%d\n", x); });
    asm ("Lforeach_done: nop; nop; nop; nop; nop; nop; ");

    return 0;
}

создает сборку, в которой лямбды 2*x и printf полностью встроены.

# 9 "x.cpp" 1
    Ltransform_begin: nop; nop; nop; nop; nop; nop; 
# 0 "" 2
    .align 4,0x90
L13:
    sall    (%rax)
    addq    $4, %rax
    cmpq    %rax, %r12
    jne L13
# 13 "x.cpp" 1
    Lforeach_begin: nop; nop; nop; nop; nop; nop; 
# 0 "" 2
    .align 4,0x90
L14:
    movl    (%rbx), %esi
    leaq    LC0(%rip), %rdi
    xorl    %eax, %eax
LEHB1:
    call    _printf
LEHE1:
    addq    $4, %rbx
    cmpq    %r12, %rbx
    jne L14
# 17 "x.cpp" 1
    Lforeach_done: nop; nop; nop; nop; nop; nop; 
# 0 "" 2
9 голосов
/ 22 июля 2010

Возможно, что лямбда-выражение может быть встроенным.Под капотом лямбда-выражение ничем не отличается от любого другого функционального объекта.

То, является ли конкретное лямбда-выражение встроенным, полностью зависит от компилятора и решит, стоит ли его вставлять.

3 голосов
/ 22 июля 2010

Если у вас есть обычный структурный функтор, компилятор почти наверняка встроит его.Если у вас есть лямбда в стиле C ++ 0x, компилятор почти наверняка встроит ее.Если вы используете boost :: lambda, то это может подойти в зависимости от того, как работает lambda под сценой.Короткая версия: Вы не можете гарантировать, что он встроенный или не встроенный, но вы должны доверять своему компилятору и, если сомневаетесь, сделать его встроенным простым и легким.

1 голос
/ 22 июля 2010

Я не смотрел на вывод из лота из них каким-либо образом, но до сих пор все из них, на которые я смотрел, были встроены.

0 голосов
/ 22 июля 2010

C ++ 1x 'lambdas будет генерировать обычные функциональные объекты. Они могут быть встроены компилятором.

Были ли какие-либо измерения, которые вы сделали, предполагали, что компилятор не вставил их в место, где это приводит к заметной потере производительности?

...