Hi Gerhard,
I've been playing around with your toy example, and as far as lambda functions go, it will only perform better if the alternative is an actual (not inline) function call.
Consider the two following functions (not inlined so I can find the assembly code):
static __attribute__ ((noinline)) double do_things_lambda(const Hits &c) { // define a predicate auto layer2 = [](const Hit& h) { return h.layer() == 2; };
// define an operation.. double x = 0; auto sumx = [&x](const Hit& h) { x += h.x(); };
// and... action! . for ( const auto& hit : c ) { if (!layer2(*hit)) continue; sumx( *hit ); }
return x; }
static __attribute__ ((noinline)) double do_things_normal(const Hits &c) { double x = 0;
for ( const auto& hit : c ) { if (hit->layer() != 2) continue; x += hit->x(); }
return x; }
Both functions result in the same assembly code:
.LFB1852: .cfi_startproc movq (%rdi), %rax movq 8(%rdi), %rcx xorpd %xmm0, %xmm0 cmpq %rcx, %rax jne .L4 jmp .L8 .p2align 4,,10 .p2align 3 .L3: addq $8, %rax cmpq %rax, %rcx je .L7 .L4: movq (%rax), %rdx cmpl $2, 12(%rdx) jne .L3 movss (%rdx), %xmm1 addq $8, %rax cmpq %rax, %rcx cvtps2pd %xmm1, %xmm1 addsd %xmm1, %xmm0 jne .L4 .L7: rep ret .L8: ret .cfi_endproc
As for me, I'd rather see the immediately obvious code as in do_things_normal(), rather than trying to figure out what all lambda-one does.
To be continued... :)
-- Wilco