hasadh said:
for a performance critical application is it better to to use switch
case or accomplish the same using fn pointers ?
If you're using a modern optimizing compiler, then it will be very
careful to pick the best way of compiling a switch, in order to maximize
efficiency while not producing an excessively large jump table. Use
switches and depend on the compiler to do the best thing; generally it
is whether you think it is or not. Following are some of the techniques
it uses - if you must optimize, don't try to optimize any switch in your
own code until you've established for sure that it's a bottleneck with
profiling tools.
First of all, whenever the number of cases is small, meaning less than
20 or so, the code produced will almost always mimick that produced by
simple if-else branching, because this is the fastest way. Jump tables
do not benefit speed in such cases because of the time needed to load
from the table, and this includes almost all switch statements written
by hand in typical programs.
In another simple case, where the cases of the switch fill or nearly
fill a large enough contiguous range (like 1 through 50 except 13 and
27), a simple jump table would be generated. The compiler uses a density
heuristic to evaluate how "filled" the range is.
If there are a large number of values, say 200, spread widely across a
very large range, say the entire range of a 32-bit integer, then the
jump table solution is no good. A good solution in this case is to hash
the value being switched on to an index between 0 and 199, jump to the
address at this index in the jump table, and then resolve collisions, if
any, inside the case handler with if-else branching. If the compiler can
generate a perfect hash function, this is even better, as no collision
resolution is necessary. This case doesn't appear much in practice, and
so compilers don't usually deal with it. If you have a switch like this
in your code, you may want to write a preprocessing tool to emit code
which switches on the hash, has contiguous case labels, and does
collision resolution appropriately.
Finally, there's a common scheme that conditionals with jump tables: it
identifies a small number of dense ranges among the cases, decides which
range the value is in using if-else branching, then uses a jump table
within the range. This would be useful if your cases were, for example,
'0' through '9' and 'a' through 'z'. This one isn't always implemented
by compilers. If yours doesn't do it, write a separate switch statement
for each dense range of cases, and choose between them with if-else.
This has the same effect.