The jit can optimize away virtual function calls.
ParentClass g = ....might be a subclass...
for (int i=0;i<100000;i++) {
g.func(i);
}
The JIT can optimize away the vtable lookups to find func, and sometimes inline the code. Ok, maybe you could do this in C++ too. ParentClass[] g = ....might be a subclass...
for (int i=0;i<100000;i++) {
g[i].func(i);
}
Suppose 99% of g's are the same class. The JIT can optimize away most of the virtual function lookups (particularly if this is one of your hotspots). I.e. the code becomes: ParentClass[] g = ....might be a subclass...
for (int i=0;i<100000;i++) {
if (g.class == COMMONCLASS) {
inlined_func(i);
else {
g[i].func(i);
}
}
In the common case, a simple pointer comparison + inlined code is a lot faster than a function dereferene.