The only way you're going to know is to benchmark it with your
compiler. If performance is an issue, you should use the option
to provide the compiler with profiler output, and let it decide;
it will generally find the best solution. (Note that even on
a specific architecture, like Intel, the best solution in terms
of machine instructions may vary from one processor to the
next.)
In your case, the switch would probably look like:
switch ( len ) {
case 2:
// ...
break;
case 3:
// ...
break;
default:
if ( len > 3 ) {
// ...
} else {
// ...
}
}
With only two effective cases, the compiler doesn't have much to
work with. A typical implementation (without extreme
optimization) would do bounds checking, then a table lookup for
the two explicit cases. Any decent compiler will then pick up
that the comparison in your default
case corresponds to one of
the bounds checks it has already done, and not duplicate it.
But with only two cases, the jump table will probably not make
a significant difference compared to the two comparisons,
especially as you'll be out of bounds in the most frequent case.
Until you have actual profiler information that this is
a bottleneck in your code, I wouldn't worry about it. Once you
have that information, you can profile different variants to see
which is faster, but I suspect that if you use maximum
optimization and feed profiling information back into the
compiler, there will be no difference.