views:

198

answers:

8
func()
{
fun1();
fun2();
fun3();
fun4();
fun5();
fun6();
..
..
..
..
fun99();
fun100();
}

by using function pointers in C program? I need to call this program repeatedly in my program.

+3  A: 

There isn't much to optimize. You could create an initialized array of 100 function pointers and iterate through them. It might reduce the object code size a bit, but not by much, and would be slightly slower than the 100 direct calls (but not by much).

void func(void)
{
    static const void (*functions[])(void) =
    {
        fun1,  fun2,  fun3,  ..., fun10,
        ...
        fun91, fun92, fun93, ..., fun100
    }
    for (int i = 0; i < 100; i++)
         (*functions[i])();
}
Jonathan Leffler
Unless the 100 functions each take a sizable number of (identical) parameters, it won't even save much space.
RBerteig
this approach may result in poorer compiler optimization, which will happen whith inlining and peep hole
Vardhan Varma
+7  A: 

Not sure that this is really optimisation, but you use function pointers like this:

#include <stdio.h>

static void fun1 (void) {
    printf ("1\n");
}
static void fun2 (void) {
    printf ("2\n");
}
static void fun3 (void) {
    printf ("3\n");
}

static void (*fn[])(void) = {
    fun1, fun2, fun3
};

int main (void) {
    int i;
    for (i = 0; i < sizeof(fn) / sizeof(*fn); i++) {
        (fn[i])();
    }
    return 0;
}

This outputs:

1
2
3

as expected.

The best that you could hope for here is that main might be slightly smaller but that's offset by the fact that you need the function table.

It's useful in a "How does C work?" sort of way but not so useful in the real world.

Of course function pointers themselves are useful, I've used them quite a bit to do state machines and object oriented code in C. It's just that this specific example seems contrived.

If you wanted to execute them continuously, you could use:

int main (void) {
    int i = 0;
    while (1) {
        (fn[i])();
        i = (i + 1) % (sizeof(fn) / sizeof(*fn));
    }
    return 0;
}

but it would be just as good to wrap the previous for loop inside a while (1) anyway.

paxdiablo
Its not optimisation! Function pointers require a little but more processing and prevent a lot of compiler optimisation!
James Anderson
James, hence my first sentence. The chance of optimising the original code for speed using function pointers is slim to none, so I just took the opportunity to show how function pointers work.
paxdiablo
+3  A: 

If any of the funn() functions is short, you might benefit from having it inlined. You need to look through your compiler documentation and see if it supports any explicit hints from the programmer about which function(s) to inline. Sometimes merely making the functions static can help, I think.

Of course, inlining only removes the code overhead from the actual function call, which (depending on the functions) may be a very small proportion of the total runtime.

unwind
But most modern compilers are smart enough to figure out when it's worth to inline.
Tamás Szelei
+6  A: 

Why would you want to?

And what are you seeking to optimize? Code size? Run time? I would let the compiler take care of that for me (possibly hinting with some compiler options).

Even when doing embeddd programming with old/slow processors, low memory, etc, I generally don't try to optimzie at code level, suspecting that the compiler can make a better job of it (even if I drop to assembler).

I prefer to optimize my code for readability and maintainability.

As always, ymmv

LeonixSolutions
+1 - ymmv, had to google what that meant. Fits the context perfectly.
Praveen S
sorry Pravenn (+1 for forcing you to google). I sometimes forget that not everyone is American (including me).
LeonixSolutions
Btw, what *is* it that you want to optimize?
LeonixSolutions
+2  A: 

The performance of this code is likely to be dominated by the execution of the content of each function, so there is little or nothing to optimise at this level. One obvious optimisation is to place all that content in one function; but that may not be significant.

To be honest; if I saw such code I'd be asking serious questions about the design before attempting to optimise execution. That is not to say that there is a better solution, merely that it looks unusual, so begs a question.

Clifford
+3  A: 

Using function pointers for this is very unlikely to give you speed optimizations. Firstly, you'd be adding 100 pointers to the functions. Second, the functions now have to be called through memory indirection, which is slower than a direct call. Third, your compiler will have a harder time doing function inlining.

The specifics of just how performance is affected will depend on compiler and target platform, but for x86 you really don't want to go the function pointer route unless the functions take a fair amount of identical parameters. And if you want to really optimize, for readability as well as speed, you need to refactor.

EDIT

If we assume 32bit x86 and a normal compiler, and all functions taking no arguments, doing 100 sequential calls will take up 500 bytes at the call site, since call is encoded as E8 + four byte eip-relative destination offset.

Converting to function pointers, you'll end up with a pointer table taking 400 bytes (it's possible that this could be encoded smaller, but since we aren't told where funcNNN are defined nor compiler, I'll assume 100 standard 32bit pointers). In addition to that, you need code to iterate through the pointer array and call the functions; this code depends on your compiler, the Visual C++ 2010 generated code is 16 bytes. So you've saved a mere 84 bytes, at the cost of execution speed.

Without knowing more about the functions called, it's a bit hard commenting much further.

snemarch
Interesting maths. That suggests that on a 64-bit system, the pointers to functions the gain would be even less. Not quite a pessimization, but close. (9 bytes per function call vs 100 * 8 + 24 (guess) - about the same absolute saving, but a smaller percentage saving.
Jonathan Leffler
+1  A: 

As per above it just optimises the code size ,readbality in main() rather than any actual performance improvement.I could not understand what kind of optimisation he really wants.Please clarify?

Santosh kumar
+2  A: 
cc -O3 ......................

Will optimise this more efficiently than any human could.

James Anderson
-1: a skilled programmer can *always* reach the level of the compiler generated code. And *often*, it's not that hard to beat your compiler by dipping into assembly; whether it's worth it depends a lot on your situation, though.
snemarch
Key words "will optimise THIS" -- leaving the code as is and letting the optimiser inline etc. is the best he could do in this situation. :-)
James Anderson
Yeah, I'm going to vote this up. A skilled programmer will never reach the insane optimisations done by gcc at high levels when all they're working with is the C code. Inline or converted assembly, yes, but not raw C.
paxdiablo
Fair, removed downvote. I agree there's not much *you* can do to optimize the above code sequence without decent refactoring
snemarch
+1 30 years ago I could regularly rewrite the assembler genrated by compilers and optimize it, or make patch space, etc Nowadays I woudln't dream of trying - and improved hardware makes the effort even less meaningful
LeonixSolutions