Performance wise: f() vs code duplication vs goto


#1

In a processBlock() I have a code block (can't be inlined, it's about 25 lines and with a for loop inside) that should be executed in few places.

I can wrap this code block into a function (as a common sense suggests... but there is a function call performace penalty) or simply duplicate it where I need it or use "the evil" goto statement.

What will be the better choice?

On the first sight it looks like goto is best choice but I'm affraid that using goto can make compilers life harder and it could fail to do optimization work properly...


#2

Use a function.
If it’s slow, a function will also make it very easy to spot it as the bottleneck when using a profiler.


#3

The function isn't slow... I'm talking about function call itself comparing to goto or code duplication.

Using function is a right way (although it will cause an overhead), but using goto is very tempting shortcut.  smiley


#4

Use a function. Don't use goto.

Compilers are smart these days, and will almost certainly do a better job of deciding what to inline than a human can.


#5

I've got a whole bunch of function calls in my processblock stuff. I'd drive myself crazy otherwise trying to understand what was going on!

 

I gave myself a little time the other day to look at some compiler optimisation.  Here's a cracking example - originally I was double checking there wasn't any overhead from a getter or setting.  

Then I put a loop in:

 


#include <stdio.h>


class Object {

public:

    Object() {

        x = 1.0; 

        v = 1.0;

        }

    float get() { return v; }

    float x;

private:

    float v; 

};

    


int main () {

    Object o; 

    float result; 

    

    result = o.get(); 

    

    printf("%f", result);

    label:

    

    result = o.x;

    printf("%f", result);    

    for (int i = 0; i<10; i++) {

    o.x += 1.0; 

        printf("%f", o.x);    

    }


}


And here's the assembly - look at my poor loop! :)


    .section    __TEXT,__text,regular,pure_instructions

    .section    __TEXT,__literal8,8byte_literals

    .align    3

LCPI0_0:

    .quad    4607182418800017408     ## double 1

LCPI0_1:

    .quad    4611686018427387904     ## double 2

LCPI0_2:

    .quad    4613937818241073152     ## double 3

LCPI0_3:

    .quad    4616189618054758400     ## double 4

LCPI0_4:

    .quad    4617315517961601024     ## double 5

LCPI0_5:

    .quad    4618441417868443648     ## double 6

LCPI0_6:

    .quad    4619567317775286272     ## double 7

LCPI0_7:

    .quad    4620693217682128896     ## double 8

LCPI0_8:

    .quad    4621256167635550208     ## double 9

LCPI0_9:

    .quad    4621819117588971520     ## double 10

LCPI0_10:

    .quad    4622382067542392832     ## double 11

    .section    __TEXT,__text,regular,pure_instructions

    .globl    _main

    .align    4, 0x90

_main:                                  ## @main

    .cfi_startproc

## BB#0:

    pushq    %rbp

Ltmp3:

    .cfi_def_cfa_offset 16

Ltmp4:

    .cfi_offset %rbp, -16

    movq    %rsp, %rbp

Ltmp5:

    .cfi_def_cfa_register %rbp

    pushq    %rbx

    pushq    %rax

Ltmp6:

    .cfi_offset %rbx, -24

    leaq    L_.str(%rip), %rbx

    movsd    LCPI0_0(%rip), %xmm0

    movq    %rbx, %rdi

    movb    $1, %al

    callq    _printf

    movq    %rbx, %rdi

    movsd    LCPI0_0(%rip), %xmm0

    movb    $1, %al

    callq    _printf

    movsd    LCPI0_1(%rip), %xmm0

    movq    %rbx, %rdi

    movb    $1, %al

    callq    _printf

    movsd    LCPI0_2(%rip), %xmm0

    movq    %rbx, %rdi

    movb    $1, %al

    callq    _printf

    movsd    LCPI0_3(%rip), %xmm0

    movq    %rbx, %rdi

    movb    $1, %al

    callq    _printf

    movsd    LCPI0_4(%rip), %xmm0

    movq    %rbx, %rdi

    movb    $1, %al

    callq    _printf

    movsd    LCPI0_5(%rip), %xmm0

    movq    %rbx, %rdi

    movb    $1, %al

    callq    _printf

    movsd    LCPI0_6(%rip), %xmm0

    movq    %rbx, %rdi

    movb    $1, %al

    callq    _printf

    movsd    LCPI0_7(%rip), %xmm0

    movq    %rbx, %rdi

    movb    $1, %al

    callq    _printf

    movsd    LCPI0_8(%rip), %xmm0

    movq    %rbx, %rdi

    movb    $1, %al

    callq    _printf

    movsd    LCPI0_9(%rip), %xmm0

    movq    %rbx, %rdi

    movb    $1, %al

    callq    _printf

    movsd    LCPI0_10(%rip), %xmm0

    movq    %rbx, %rdi

    movb    $1, %al

    callq    _printf

    xorl    %eax, %eax

    addq    $8, %rsp

    popq    %rbx

    popq    %rbp

    ret

    .cfi_endproc


    .section    __TEXT,__cstring,cstring_literals

L_.str:                                 ## @.str

    .asciz    "%f"



.subsections_via_symbols