Efficiency of C ++ Virtual Functions

I am trying to get a better idea of ​​the performance of virtual functions, here is a sample code:

  struct foo {
     virtual void function1 ();
     virtual void function2 () {function1 ();  }
 };

 struct Bar: Foo {
     virtual void function1 ();
 }

 Bar b;
 Foo & f = b;

 b.function2 ();
 b.function1 ();
 f.function2 ();

for each of the three calls in the last three lines of the code sample, should they all look for a function pointer in a virtual table? how long to search for object f. which can one day be built in by the compiler?

thanks

+4
source share
6 answers

Calls to b are static - the compiler knows exactly the compile time what type of b will be at runtime (obviously Bar), so it will directly use the addresses of the methods that will be called.

A virtual question matters only when making a call using a pointer / link, because during a call, different goals can have different goals. It matters if, for example, you called function1 on a pointer and at runtime changed the actual type pointed to by the pointer.

Now the situation here, where you call function2 on f, is complicated for two reasons: the function is never redefined and you use a link that cannot be reassigned. Thus, a really smart compiler that sees all the input files can understand that the purpose of the call will really be with 100% trust (since you are not going to add new classes to already compiled code). However, AFAIK, compilers should not do this for you to pay the costs.

Generally speaking, if you do not plan to redefine any function, do not make it virtual.

+7
source

Alan Ruskin did a test on this topic:

http://assemblyrequired.crashworks.org/2009/01/19/how-slow-are-virtual-functions-really/

Of course, it's up to you how practical the results are for you :-)

+5
source

You can try it here. Wrap these three function calls in a loop with a million iterations. Then run the program through the profiler to understand what the difference in cost is. If you run linux, callgrind (profiler) and kcachegrind (visualize the results), you will get a great idea about this, down to the level of assembler code.

0
source
In C++, To achieve run-time polymorphism 2 things are required: 1. Function must be a member of the class and declared as virtual. 2. Use Pointers or references to make dynamic function dispatch possible. eg Derived d; Base &refBase = d; Base *pBase = d; d.foo(); // resolved at compile time based on the static type of object (Derived) refBase.foo(); //will resolve at runtime /* Here refBase is reference to Base class , but its dynamic type reference to Derived class object so its referring to derived class object and accordingly derived class function is called (using look up in vtbl) and similarly for pointers. */ So in your case first 2 function calls are resolved at compiler time since invoked by object rather than pointers or references . The last call will be resolved at run-time by making lookup in vtable of derived class. 
0
source

The actual method call takes about twice as much for the virtual method. Keep in mind that an attachment does not accept anything. If you are okay with the call in the first place, you are usually fine with a virtual call, and when you cannot, you can often rebuild it. Especially remember that the call time does not affect the actual code, which then runs.

0
source

These days, the performance implications are negligible. Even in games or other code with a high degree of performance.

0
source

All Articles