Are C ++ virtual functions implemented in a polymorphic base class as fast as calling a C-style function pointer? Is there any difference?
Apples and oranges. At the minimum one-to-one level, the level of calling a virtual function requires a bit more work, since there is overhead information about specifying / indexing to switch from vptr to vtable .
But calling a virtual function can be faster
Well, how could that be? I just said that calling a virtual function requires a bit more work, which is true.
What people tend to forget is to try to make a closer comparison here (to try to make it a little smaller than apples and oranges, although these are apples and oranges). Usually we do not create a class with one virtual function. If we did this, then performance (as well as even things like code size) would definitely support a function pointer. We often have something more:
class Foo { public: virtual ~Foo() {} virtual f1() = 0; virtual f2() = 0; virtual f3() = 0; virtual f4() = 0; };
... in this case, there may be more โdirectโ analogies to a function pointer:
struct Bar { void (*f1)(); void (*f2)(); void (*f3)(); void (*f4)(); };
In this case, calling virtual functions in each case Foo can be significantly more efficient than Bar . This is because Foo only needs to store one vptr for the central vtable, which is accessed more than once. At the same time, we get improved locality of links (fewer Foos and those that can potentially fit better and in number in the cache line, more frequent access to the central vtable Foo's ).
Bar , on the other hand, requires more memory and effectively duplicates the contents of Foo's vtable in each instance of Bar (let's say there are a million instances of Foo and Bar ). In this case, the amount of redundant data inflating the size of Bar often far outweighs the cost of doing a little less work to call a pointer to a function.
If we only needed to save one pointer to an object, and it was a very strong spot, then it would be nice to just save a pointer to a function (for example: it can be useful for those who implement everything that remotely resembles std::function just to save a pointer per function).
So, itโs kind of apples and oranges, but if we model an example of use, then close to this, an approach like vtable, which stores a central common table of function addresses (in C or C ++), can be much more efficient.
If we simulate a use case in which we have only one function pointer stored in an object vs. vtable, which has only one virtual function, then the function pointer will be somewhat more efficient.