Branching vs array indexing

I was wondering... if I had many different functions that I wanted to call based on what the value of a variable would be, and the limits of that value where integral [0, N) , would the second method be much faster than the first?:

In my opinion indexing is more useful and I try to use it when I can. Indexing is an important operation to consider, especially if you want to speed up something nontrivial like random file access. Sometimes I just do it this way for the practice.

The compiler may very well optimize a switch into a function table. Regardless, don't concern yourself about it. Let the compiler do its work, while you keep the code readable.

Premature optimization.
The compiler may very well optimize a switch into a function table. Regardless, don't concern yourself about it. Let the compiler do its work, while you keep the code readable.

Second that. Even if you optimize it to save 1ms (a LOT of time in computing) per run, you would need a lot of runs to compensate for the one additional working day (28.800.000ms) your colleague needs to understand your program because you optimized it for speed. Optimize for readability while keeping it "fast enough" is probably more rewarding.

That said I think your second approach using a table would indeed be more readable as the number of functions increases. I would not want to read a 2000 line switch statement where I can never be sure if there isn't one case that is not just the single function call. So it's win-win. Probably faster, most likely more readable.

hth
-nv

She was so Blonde, she spent 20 minutes looking at the orange juice can because it said "Concentrate."

Thanks guys. I asked this because I've been building some old PC emulators( like Kenbak-1 ), and I thought I could use the opcodes as indices! It'd be nice if I managed to get it to run at approx 300 IPS( speaking about the Kenbak-1 ) with less than 5% of my CPU( Core2 Duo 2.4GHz ) .

I use a function pointer table in one of my big programs, because there are literally hundreds of entries. a switch statement in my case would be insanely huge and unreadable. if C++ had reflection, I might be able to use that instead, but the function pointer table works great for my purposes. it's fast, it's obvious what it does, and it's easy to add elements when necessary.

Essentially, it jumps directly to the right position in the switch, then performs the call. If I enable inlining, it inlines the functions directly into the switch.
Not a direct function table call, but almost. But that's what I meant, if it isn't clear. The compiler can optimize the switch to essentially jump to the right position.
Dunno if a compiler is smart enough to understand that all cases essentially just call a function, though.

Originally Posted by Adak

io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.

Originally Posted by Salem

You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

I believe compilers will turn switch into jump table for you only if the indices are more or less continuous. Otherwise memory space wasted would be significant, especially if it decreases code density to the point that you get more instruction cache misses, then it would definitely not be worth it.

map<"some kind of key", object> .... have the objects inherit from an abstract class which has a public void function like "execute()", then you can insert various objects in there that do different jobs, and fire them all off using the same command after you've looked up what you want (command pattern)

Maybe I just spoke craziness there. Don't know. I'm trying to translate java style OO with interfaces into "c++ style". Either way, I'm quite sure I can count on a good chastising if I am wrong on any count.

I made a pair of "Braille Gloves" which have 6 vibration motors in six finger tips and vibrate in the relevant patterns. I have used this to read stuff while out walking. Given there is a fairly well defined programmer-oriented Braille encoding I should imagine it would work in this situation. Diagrams could be a pain still.

Note: I am not blind but have learnt Braille fairly easily so for me it works quite well

In other words, if several cases follow easily discernible linear mathematics the compiler may build a table for parts of the `switch' and branch otherwise as appropriate.

From some testing, I don't think GCC does mix and match, but I think MSVC does. I may be wrong though, not great at reading x86 disassembly.

On the original question... I completely agree with what's already been said. Use whatever is appropriate and most readable/maintainable for the task at hand. For what you said (building an emulator) I'd probably opt for the table approach.

I don't know if it'll be any faster than the optimised-switch code. You've saved a branch, but gained array index and load of the function address. I'd guess it'll work out about the same.

I think "optimised" C/C++ can be useful and has its place. The programmer will know things about the application that the compiler can't know or coudln't be expected to figure out, so the programmer can write their code in a way that expresses their intent explicitly or implicitly to the compiler. I think treading on the compiler's standard optimisation turf is less likely to be useful, as you don't have total control of what is output.

Originally Posted by wildcard_seven

map<"some kind of key", object> .... have the objects inherit from an abstract class which has a public void function like "execute()", then you can insert various objects in there that do different jobs, and fire them all off using the same command after you've looked up what you want (command pattern)

Maybe I just spoke craziness there. Don't know. I'm trying to translate java style OO with interfaces into "c++ style". Either way, I'm quite sure I can count on a good chastising if I am wrong on any count.

lol, no chastising from me.... much too OO for me to comment. Didn't sound crazy until I looked up the command pattern -- looks, err, rather heavyweight!