In my undetrstanding, for a C++ virtual call, it needs to:
While for a non-virtual (such as in C) call, only #4 is required.
I think that #3 should be the most time consuming. Given the nature of realtime overriding in C++, I could not see much potential for compilation time optimization for the above steps. Thus for a complex class inheritance with long function signatures, a C++ virtual call should be much slower than a non-virtual call.
But all claims are contrary, why?
Virtual functions are slow when you have a cache miss looking them up. As we'll see through benchmarks, they can be very slow. They can also be very fast when used carefully — to the point where it's impossible to measure the overhead.
Virtual functions are by definition slower than their non-virtual counterparts; we wanted to measure the performance gains from inlining; using virtual functions would make the difference even more pronounced.
So polymorphic behaviour works even when a virtual function is called inside a non-virtual function. The output can be guessed from the fact that the function to be called is decided at run-time using the vptr and vtable.
Virtual functions ensure that the correct function is called for an object, regardless of the type of reference (or pointer) used for function call. Functions are declared with a virtual keyword in base class. The resolving of function call is done at runtime.
- Get the type of the object from the symbol table
- Get the v-table from the type table
- Search the function using the function signature in the v-table
- Call the function.
This is a poor understanding of how v-table-based dispatch works. It's much simpler:
Each object has a v-table pointer, which points at the v-table for that object's original type. So there's no need to fetch the type from a "symbol table". No searching of the v-table is necessary. It's compile-time determinable exactly which pointer in the v-table needs to be accessed, based on the function signature provided at compile time. It's all about how the compiler indexes each virtual function in a class. It can determine a specific order for each virtual function, and thus when the compiler goes to call it, it can determine which function to call.
So it's quite fast overall.
It's a bit more complex when dealing with virtual base classes, but the general idea is still the same.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With