This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Virtual Functions and Performance C++
Is this correct, that class member function takes more time than a simple function? What if inheritance and virtual functions are used?
I have tried to collect my functions into a simple interface class (only member functions, no data members), and it appears that I lose time. Is there a way to fix it?
P.S. I'm checking with gcc and icc compilers and using -O3 option.
Premature optimization is the root of all evil
A nonstatic member function takes an additional argument, which is the object (a pointer or reference to it) on which the function is called. This is one overhead. If the function is virtual, then there is also one small indirection in case of a polymorphic call, that is, addition of the function index to the virtual table base offset. Both of these "overheads" are sooo negligable, you shouldn't worry about it unless the profiler says this is your bottleneck. Which it most likely is not.
Premature optimization is the root of all evil
Member functions, if they're not virtual, are same as free functions. There is no overhead in its invocation.
However, in case of virtual member functions, there is overhead, as it involves indirection, and even then, it is slower when you call the virtual function through pointer or reference (that is called polymorphic call). Otherwise, there is no difference if the call is not polymorphic.
There is no additional time penalty involved for member functions. Virtual functions are slightly slower but not by much. Unless you're running an incredibly tight loop, even virtual function overhead is negligible.
For normal functions it's enough with a "jump" to them, which is very fast. The same goes for normal member functions. Virtual functions on the other hand, the address to jump to has to be fetched from a table, which of course involves more machine code instructions and therefore will be slower. However, the difference is negligible and will hardly even be measurable.
In other words, don't worry about it. If you have slowdowns, then it's most likely (like 99,999%) something else. Use a profiler to find out where.
Related
Considering the fact that a pointer to a function returning another pointer to another function is the mechanism used in C to introduce some runtime polymorphism/callbacks, What is the equivalent way to implement this in C++ while improving locality and lower the cost about pointers and indirections ?
For example this syntactic sugar can help but I'm not really interested in this, altough it's a nice way to do things in a C++ way instead of a more C-ish typedef, I'm more interested in improving locality while trying to reduce the use of explicit pointers at runtime.
The real reason as to why people use function pointers in C to emulate polymorphism is not performance but the fact that C neither supports real polymorphism nor templates. These are two alternatives you have in C++. All three approaches are compared in this thread.
Note that even though calling a function pointer does not require the additional vtable lookup that virtual function calls do, calling virtual functions and function pointers both suffer from the same major performance problem: Branch prediction in both cases is not as reliable and you tend to end up with more pipeline flushes.
I think you can use Virtual function for meet part of the requirement.
This question already has answers here:
Is there any reason not to make a member function virtual?
(7 answers)
Closed 4 years ago.
I hope this question is not too vague, but coming from java, I can not think of any reason why I would use non-virtual functions in C++.
Is there a nice example which demonstrates the benefit of non-virtual functions in C++.
Virtual functions have a runtime cost associated with them. They are dispatched at runtime and thus are slower to call. They are similar to calling regular functions through a function pointer, where the address is determined at runtime according to the actual type of the object. This incurs overhead.
One of the C++ design decisions has always been that you should not pay for things you don't need. In contrast, Java does not concern itself much with this kind of low-level optimization.
It is true that calling a virtual function can be slower, but not nearly as slow as most C++ programmers think.
Modern CPUs have gotten pretty good at branch prediction. If, every time you execute a particular call to a virtual function, you are actually calling the same implementation, the CPU will figure that out and start "guessing" (speculatively executing) the call before it even computes the address. This can often hide the cost of the virtual call completely, making it exactly as fast as a non-virtual call. (If you doubt this, try it for yourself on a current-generation processor.)
If you are not calling the same implementation, then you are actually relying on the virtual dispatch, so you could not directly replace it with a non-virtual function anyway.
The only common exception to this is inlined functions, where the compiler can perform constant propagation, CSE, etc. between the caller and callee. Obviously it cannot do this if it does not know the destination of the call at compile time.
But as a rule of thumb, your instinct that you always want to use virtual functions is not all that bad. The times when the performance difference is noticeable are rare.
Very few member functions in the standard library are virtual.
Offhand I can only remember the destructor and what function of standard exceptions.
As of 2012 the only good reason to have a virtual member function is to support overriding of that member function in a derived class, i.e. a customization point, and that can often be achieved in other ways (e.g. parameterization, templating).
However, I can remember at one time, like 15 years ago, being very frustrated with the design of Microsoft's MFC class framework. I wanted every member function to be virtual so as to be able to override the functionality and in order to be able to more easily debug things, as an alternative to non-existing or very low quality documentation. Thus, I argued that virtual should be the default, also in other software.
I have since understood that MFC was not representative and is not representative of C++ software in general, so the MFC-specific reasons do not apply in general. :-)
The efficiency cost of virtual function is, like, virtually non-existent. :-) See for example the international standarization committee's Technical Report on C++ Performance. However, there is a real cost in providing this freedom for derived classes, because freedom implies responsibility: any derived class then has to ensure that overriding the member function respects the contract of the base class.
Well, one of the principles on which C++ language is based is that you should not pay for something you don't use.
Virtual function call is more expensive than non-virtual function call, since in a typical implementation it comes through two (or three) additional levels of indirection. A virtual call cannot be inlined, meaning that the expenses can grow even higher due to fact that we have to call a full-fledged function.
Adding virtual functions to an class makes it polymorphic, thus creating some invisible internal structures inside objects of that class. These structures incur additional household expenses and preclude low-level processing of class objects.
Finally, separating functions into virtual and non-virtual ones (i.e into overridable and non-overridable ones) is a matter of your design. It simply makes no sense whatsoever to unconditionally make all functions in our class overridable in the derived classes.
C++ is meant to be both fast like C, and support OO and generic programming (templates). To achieve both this goals, C++ member functions by default can't be inerited, unless you mark them as virtual, in which case the virtual table gets into business. So you can build classes that don't involve virtual functions, when not needed.
Although not as efficient as non-virtual calls, virtual functions calls using the virtual table are very fast. You might notice the different only within tight loops that do nothing but calling a member function. So the Java way - all members are "virtual" - is indeed more practical IMO.
If i call an inherited method on a derived class instance does the code require the use of a vtable? Or can the method calls be 'static' (Not sure if that is the correct usage of the word)
For example:
Derived derived_instance;
derived_instance.virtual_method_from_base_class();
I am using msvc, but i guess that most major compilers implement this roughly the same way.
I am (now) aware that the behavior is implementation-specific, i'm curious about the implementation.
EDIT:
I should probaby add that the reason that we are interested is that the function is called a lot of times, and it is very simple, and i am not allowed to edit the function itself in any way, i was just wondering if would be possible, and if there would be any benifit to eliminating the dynamic-dispach anyway.
I have profiled and counted functions etc etc before you all get on my backs about optomization.
Both of your examples will require that Derived has a constructor accepting a Base and create a new instance of Derived. Assuming that you have such a constructor and that this is what you want, then the compiler would "probably" be able to determine the dynamic object type statically and avoid the virtual call (if it decides to make such optimizations).
Note that the behavior is not undefined, it's just implementation-specific. There's a huge difference between the two.
If you want to avoid creating a new instance (or, more likely, that's not what you want) then you could use a reference cast static_cast<Derived&>(base_instance).virtual_method_from_base_class(); but while that avoids creating a new object it won't allow you to avoid the virtual call.
If you really want to cast at compile time what you're looking for is most likely the CRTP http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern which allows you to type everything at compile time, avoiding virtual calls.
EDIT for updated question: In the case you've shown now, I would suspect many compilers capable of statically determining the dynamic type and avoiding the virtual call.
Vtable only come into play when you use pointers or references. For objects, it's always the specific class method which is invoked.
You can simply qualify the call, then there is no virtual function dispatch:
Derived derived_instance;
derived_instance.Derived::virtual_method_from_base_class();
However, I suspect that that would be premature optimization.
Do measure.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
A question about virtual mechanism in C++
Is using vtable the only way to implement virtual member functions mechanism in C++? What other ways exist?
Technically, all that's required for dynamic dispatch is the ability to identify the dynamic type of an object, given a pointer to it. Thus, any sort of hidden (or not-so-hidden) typeid field would work.
Dynamic dispatch would use that typeid to find the associated functions. That association could be a hastable or an array where typeid is the index, or any other suitable relationship. vptr just happens to be the way to achieve this in the least number of steps.
Another known mechanism is type dispatch functions. Effectively, you replace the vtable pointer by a typeid (small enum). The (dyanmic) linker collects all overrides of a given virtual function, and wraps them in one big switch statement on the typeid field.
The theoretical justifcation is that this replaces an indirect jump (non-predicatble) by lots of predicatable jumps. With some smarts in choosing enum values, the switch statement can be fairly effective too (i.e. better than lineair)
Another possible implementation would be to store the pointers to virtual functions directly into the objects. Of course, this solution is never used in practice (at least in no languages I'm aware of) since it would lead to a dramatic increase of the memory footprint. However, it is interesting to note that a code using this implementation could actually run faster since it removes an indirection layer by suppressing the need for the vptr.
I'm not aware of any compiler which implements virtual functions without using vtable approach.
Theoretically, however, one could create an internal map of object pointers and a table of pointers to virtual functions, something like map<objPtr, functionTable*>, to implement dynamic polymorphism through virtual functions. But then it would make the dynamic dispatching slower than vtable-approach.
It seems vtable-approach is probably the fastest mechanism to implement dynamic polymorphism. Maybe, that is why all compilers employ this approach!
And why don't we use the same method for non virtual functions?
I mean, why do we use virtual functions in that way? Can't we just use them as non-virtaul ones and override them?
And if this method is saving us time/space or what ever, why don't we use the same method for non-virtual functions? I mean it would make sense that there would be one table of functions for a specific class.
Anyway, thanks in advance, I am just a bit confused.
You can't have run-time polymorphism without using a level of indirection. That's what the vptr is for.
The vptr is not used for non-polymorphic functions because that indirection costs something. The C++ philosophy is that you don't pay for what you don't use.
EDIT:
Here's some info on how virtual tables work: http://en.wikipedia.org/wiki/Virtual_table
The compiler essentially generates a direct call to non-virtual methods. With a virtual method call, the compiler generates code to lookup the address of the method and then makes a call to that address. Thus, it is, in theory, at least one more lookup when calling a virtual function. There would be no reason to incur that cost otherwise.
Using vptr allows method resolution based on object type rather than variable type. Not using vptr makes method calls faster. The C++ designers decided to allow the convenience of virtual functions but not require the performance penalty for other functions.