Home > Mobile >  Using function pointers is slower than switch statement
Using function pointers is slower than switch statement

Time:10-26

I have this piece of code for testing the behaviour of switch statement versus function pointers:

#include <stdio.h>
#include <time.h>


int mySum(int startingValue)
{
    return startingValue  = 1;
}

int mySub(int startingValue)
{
    return startingValue -= 1;
}


int main()
{
    time_t rawtime;
    struct tm * timeinfo;

    time(&rawtime);
    timeinfo = localtime(&rawtime);
    printf("USING SWITCH\n");
    printf("Start time: %s", asctime(timeinfo));

    int startingValue = 25;
    int currentOperation = 0;

    // Using switch
    for (long long i = 0; i < 10000000000; i  )
    {
        switch (currentOperation)
        {
            case 1:
                startingValue = mySum(startingValue);
                break;
            case 0:
                startingValue = mySub(startingValue);
                break;
        }

        if (currentOperation)
            currentOperation = 0;
        else
            currentOperation = 1;
    }

    printf("Result is: %d\n", startingValue);

    time(&rawtime);
    timeinfo = localtime(&rawtime);
    printf("End time: %s", asctime(timeinfo));

    printf("\n\n\n");

    time(&rawtime);
    timeinfo = localtime(&rawtime);
    printf("USING FUNCTION POINTERS\n");
    printf("Start time: %s", asctime(timeinfo));

    startingValue = 25;
    currentOperation = 0;

    // Using function pointers
    int (*mySwitchOfFunctionPointers[2])(int x);
    mySwitchOfFunctionPointers[0] = &mySub;
    mySwitchOfFunctionPointers[1] = &mySum;
    for (long long i = 0; i < 10000000000; i  )
    {
        startingValue = (*mySwitchOfFunctionPointers[currentOperation])(startingValue);

        if (currentOperation)
            currentOperation = 0;
        else
            currentOperation = 1;
    }

    printf("Result is: %d\n", startingValue);

    time(&rawtime);
    timeinfo = localtime(&rawtime);
    printf("End time: %s", asctime(timeinfo));

    return 0;
}

The output is this so code executes instantly with switch statement but it needs many seconds with function pointers:

USING SWITCH
Start time: Mon Oct 25 18:04:06 2021
Result is: 25
End time: Mon Oct 25 18:04:06 2021



USING FUNCTION POINTERS
Start time: Mon Oct 25 18:04:06 2021
Result is: 25
End time: Mon Oct 25 18:04:34 2021

Compiled with

gcc -c main.c -o test.o -O3 -Wall -Wno-unused -std=c99
gcc test.o -o test

Why the second approach is slower than the first??? Is there something wrong in the code? Any idea?

CodePudding user response:

The compiler can inline the switch and then the optimizer is smart enough to realize that your entire loop is a no-op so optimizes it out. It does not do this with the function pointers. See https://godbolt.org/z/qxxoof5cn

If you change your code to something that the compiler cannot optimize out so trivially you will get very different results. For example:

int mySum(int startingValue)
{
    return startingValue  = rand();
}

int mySub(int startingValue)
{
    return startingValue -= rand();
}

CodePudding user response:

The compiler optimization argument (-O3) is responsible for this behaviour.

The compiler can optimize the first for-Loop with the switch inside, because it has every needed information about this code.

Unfortunately the compiler can't optimize code with function-pointers. Since the compiler do not know what functions are called.

If you delete the -O3 argument at compiling, you will see that, function pointers and the switch-case statements need similar times.

  • Related