For example, there are measurable differences in branch prediction based on whether each opcode's implementation ends with its own dispatch code or branches back to a common dispatch routine. The sequence of instructions is basically the same in both cases, but there is an icache/branch prediction tradeoff to be made. Subtle stuff (see http://repo.or.cz/w/luajit-2.0.git/blob/0ded8e82a88fadb40b4d...)
I often hear this from programmers coming from a higher-level background. O(1) only means constant time. It doesn't mean quickly. This function:
int foo(int x) {
sleep(3600);
return x;
}
is O(1), just as this: int bar(int x) {
return x;
}
Foo takes an hour to commplete, but it's just as O(1) as bar :-).switch is O(1) and fast as the operation is usually 2-3 deterministic time instructions:
1. Look up jump address from lookup table made by compiler.
2. Jump to it.
More people need to have written assembly to actually get this into their heads.
jmp [lookupTable + eax]In general, if I need something to avoid function calls, I'll use macros as a shorthand for a complex expression (like NEXT_BYTE) and inline functions for anything that involves one or more full statements (like set_flags). Obviously I don't follow that too dogmatically, because mem_abs is an inline function.