I have hotspot code which runs in a tight loop:
for (i = 0; i < big; i++)
{
    if (condition1) {
        do1();
    } else if (condition2) {
        do2();
    } else {
        do3();
    }
    // Shared code goes here
    // More shared code goes here
}
Since condition1 and condition2 are invariant, I unswitched the loop to
if (condition1) {
    for (i = 0; i < big; i++)
    {
        do1();
        // Shared code goes here
        // More shared code goes here
    }
} else if (condition 2) {
    for (i = 0; i < big; i++)
    {
        do2();
        // Shared code goes here
        // More shared code goes here
    }
} else {
    for (i = 0; i < big; i++)
    {
        do3();
        // Shared code goes here
        // More shared code goes here
    }
}
This runs much better, but I wonder if there's a clever way to do this without repeating myself?
Another, possibly slightly more efficient option is to use a macro to construct the code for you:
#define DO_N(name, ...) for(int i = 0; i < big; i++){name(__VA_ARGS__);/*shared code*/}
if (condition1) {
    DO_N(do1, .../*arguments here*/)
} else if (condition 2) {
    DO_N(do2, ...)
} else {
    DO_N(do3, ...)
}
#undef DO_N
Its ugly, but I think it does what you want, and might allow inlining where a function pointer does not.
Additionally, you may find it more readable to put your shared code in a separate macro or function.
I think you can declare a function pointer and some function foo():
typedef void (*fp)(void);
void foo(int big, fp f) {
    for (int i = 0; i < big; ++i) {
        f();
        // Shared code goes here
        // More shared code goes her
    }
}
Then change your code for something like this:
if (condition1) {
    foo(big, do1);
} else if (condition2) {
    foo(big, do2);
} else {
    foo(big, do3);
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With