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