I know there is some positive aspects of inheritance, but I don't know negative runtime impacts of inheritance? Can anybody tell me about that, thanks!
Large inheritance based systems usually uses more memory and have worse data layout than composition based systems, this has a runtime cost in terms of speed due to how the cache behaves ( you want everything related to be as tightly packed as possible ).
Virtual function calls requires a trip to a virtual function table in order to retrieve the correct function to call, this can be costly due to cache behavior, the vtable might be far from the calling function.
Multiple inheritance increases the cost of virtual function calls further, as first an offset might need to be computed in order to get the correct vtable.
If you're using RTTI, then you'll usually see additional data at a fixed location in relation to the vtable. This affects the vtable locality, which once again prohibits the cache.
If a base class contains virtual functions then instances of it and its descendants will each have a pointer to a virtual function table, increasing their memory footprint by the size of one pointer. Calls to virtual functions will have an extra level of indirection compared to non-virtual functions, so there is a small call time cost there.
Otherwise, there is no negative impact. Deriving one class from another but not using polymorphism (so, no virtual functions, always calling methods through pointers to the derived class) has no cost over a class with no parent.
Update: I have addressed the performance impact of inheritance here. Other answers have more to say on OO-correctness.
The benefits of using inheritance greatly outweigh the downfalls.
The first downfall is the object size in memory, which, when using virtual functions, has an extra pointer to the virtual function table.
Virtual function calls also require a few extra steps in the assembly compared to regular calls.
Non-virtual function calls cost the same in terms of performance.
Object size can also increase as an object of class A, if A is derived from B, contains all information from B. Of course, with a well-thought design, this doesn't happen, because even without inheritance, A would contain all information in B.
One more issue would be the use of dynamic_cast or static_cast, which you wouldn't encounter in an inheritance-free environment, but these can also be avoided even using inheritance.
The only runtime impact could be performance in terms of memory and speed. Considering functionality-wise everything can be done without inheritance, the only question is how well it performs as opposed to the alternatives. That will depend on the specific scenarios you want to compare, and the complier's generated code.
Inheritance can negatively impact data locality, which is a big deal when you have a lot of numbers to crunch. You also get less control over data layout than when you use composition, so your objects might take up more memory.
If you also use polymorphism, then you spend additional cycles on indirect function calls and get even worse data locality, as you reference virtual function tables.
Generally, the overhead cost of object-oriented programming is fairly small and you only have to think about it when you are processing large amounts of data. Check Sony's Pitfalls of Object Oriented Programming presentation — it looks at OOP performance from a game developer's perspective.
After reading the other (informative!) responses, I believe one potential negative impact wasn't mentioned yet:
Inheritance is often used to achieve polymorphy. In C++, this means that you pass references (C++ references or pointers) to the base type around, instead of passing it by value, to avoid the slicing problem. In practice, passing references around often means that the scope of an object should no longer define its life time - so people start using dynamic memory management (say, new and delete). And this can open a whole can of worms itself.
To make a long story short: very often, inheritance goes hand in hand with dynamic memory allocation, which opens a whole new class of issues.
Since you tagged your post with C++, I'd like to add that one of the most important runtime impact when you use virtual function in C++ is related to the impossibility to expand them inline.
In fact, the heaviest performance impact is not due to the virtual function table lookup, but to the fact that the compiler cannot expand a virtual function even if you declare it as inline. This prevents an important optimization that could make your code much faster.
I would think inheritance would only improve runtime. If you rewrite the code in several places that code has to be compiled that many times more.
Related
I know that virtual functions have an overhead of dereferencing to call a method. But I guess with modern architectural speed it is almost negligible.
Is there any particular reason why all functions in C++ are not virtual as in Java?
From my knowledge, defining a function virtual in a base class is sufficient/necessary. Now when I write a parent class, I might not know which methods would get over-ridden. So does that mean that while writing a child class someone would have to edit the parent class. This sounds like inconvenient and sometimes not possible?
Update:
Summarizing from Jon Skeet's answer below:
It's a trade-off between explicitly making someone realize that they are inheriting functionality [which has potential risks in themselves [(check Jon's response)] [and potential small performance gains] with a trade-off for less flexibility, more code changes, and a steeper learning curve.
Other reasons from different answers:
Virtual functions cannot be in-lined because inlining have to happen at runtime. This have performance impacts when you expect you functions benefits from inlining.
There might be potentially other reasons, and I would love to know and summarize them.
There are good reasons for controlling which methods are virtual beyond performance. While I don't actually make most of my methods final in Java, I probably should... unless a method is designed to be overridden, it probably shouldn't be virtual IMO.
Designing for inheritance can be tricky - in particular it means you need to document far more about what might call it and what it might call. Imagine if you have two virtual methods, and one calls the other - that must be documented, otherwise someone could override the "called" method with an implementation which calls the "calling" method, unwittingly creating a stack overflow (or infinite loop if there's tail call optimization). At that point you've then got less flexibility in your implementation - you can't switch it round at a later date.
Note that C# is a similar language to Java in various ways, but chose to make methods non-virtual by default. Some other people aren't keen on this, but I certainly welcome it - and I'd actually prefer that classes were uninheritable by default too.
Basically, it comes down to this advice from Josh Bloch: design for inheritance or prohibit it.
One of the main C++ principles is: you only pay for what you use ("zero overhead principle"). If you don't need the dynamic dispatch mechanism, you shouldn't pay for its overhead.
As the author of the base class, you should decide which methods should be allowed to be overridden. If you're writing both, go ahead and refactor what you need. But it works this way, because there has to be a way for the author of the base class to control its use.
But I guess with modern architectural speed it is almost negligible.
This assumption is wrong, and, I guess, the main reason for this decision.
Consider the case of inlining. C++’ sort function performs much faster than C’s otherwise similar qsort in some scenarios because it can inline its comparator argument, while C cannot (due to use of function pointers). In extreme cases, this can mean performance differences of as much as 700% (Scott Meyers, Effective STL).
The same would be true for virtual functions. We’ve had similar discussions before; for instance, Is there any reason to use C++ instead of C, Perl, Python, etc?
Most answers deal with the overhead of virtual functions, but there are other reasons not to make any function in a class virtual, as the fact that it will change the class from standard-layout to, well, non-standard-layout, and that can be a problem if you need to serialize binary data. That is solved differently in C#, for example, by having structs being a different family of types than classes.
From the design point of view, every public function establishes a contract between your type and the users of the type, and every virtual function (public or not) establishes a different contract with the classes that extend your type. The greater the number of such contracts that you sign the less room for changes that you have. As a matter of fact, there are quite a few people, including some well known writers, that defend that the public interface should never contain virtual functions, as your compromise to your clients might be different from the compromises you require from your extensions. That is, the public interfaces shows what you do for your clients, while the virtual interface shows how others might help you in doing it.
Another effect of virtual functions is that they always get dispatched to the final overrider (unless you explicitly qualify the call), and that means that any function that is needed to maintain your invariants (think the state of the private variables) should not be virtual: if a class extends it, it will have to either make an explicit qualified call back to the parent or else would break the invariants at your level.
This is similar to the example of the infinite loop/stack overflow that #Jon Skeet mentioned, just in a different way: you have to document in each function whether it accesses any private attributes so that extensions will ensure that the function is called at the right time. And that in turn means that you are breaking encapsulation and you have a leaking abstraction: Your internal details are now part of the interface (documentation + requirements on your extensions), and you cannot modify them as you wish.
Then there is performance... there will be an impact in performance, but in most cases that is overrated, and it could be argued that only in the few cases where performance is critical, you would fall back and declare the functions non-virtual. Then again, that might not be simple on a built product, since the two interfaces (public + extensions) are already bound.
You forget one thing. The overhead is also in memory, that is you add a virtual table and a pointer to that table for each object. Now if you have an object which has significant number of instances expected then it is not negligible. example, million instance equals 4 Mega byte. I agree that for simple application this is not much, but for real time devices such as routers this counts.
I'm rather late to the party here, so I'll add one thing that I haven't noticed covered in other answers, and summarise quickly...
Usability in shared memory: a typical implementation of virtual dispatch has a pointer to a class-specific virtual dispatch table in each object. The addresses in these pointers are specific to the process creating them, which means multi-process systems accessing objects in shared memory can't dispatch using another process's object! That's an unacceptable limitation given shared memory's importance in high-performance multi-process systems.
Encapsulation: the ability of a class designer to control the members accessed by client code, ensuring class semantics and invariants are maintained. For example, if you derive from std::string (I may get a few comments for daring to suggest that ;-P) then you can use all the normal insert / erase / append operations and be sure that - provided you don't do anything that's always undefined behaviour for std::string like pass bad position values to functions - the std::string data will be sound. Someone checking or maintaining your code doesn't have to check if you've changed the meaning of those operations. For a class, encapsulation ensures freedom to later modify the implementation without breaking client code. Another perspective on the same statement: client code can use the class any way it likes without being sensitive to the implementation details. If any function can be changed in a derived class, that whole encapsulation mechanism is simply blown away.
Hidden dependencies: when you know neither what other functions are dependent on the one you're overriding, nor that the function was designed to be overridden, then you can't reason about the impact of your change. For example, you think "I've always wanted this", and change std::string::operator[]() and at() to consider negative values (after a type-cast to signed) to be offsets backwards from the end of the string. But, perhaps some other function was using at() as a kind of assertion that an index was valid - knowing it'll throw otherwise - before attempting an insertion or deletion... that code might go from throwing in a Standard-specified way to having undefined (but likely lethal) behaviour.
Documentation: by making a function virtual, you're documenting that it is an intended point of customisation, and part of the API for client code to use.
Inlining - code side & CPU usage: virtual dispatch complicates the compiler's job of working out when to inline function calls, and could therefore provide worse code in terms of both space/bloat and CPU usage.
Indirection during calls: even if an out-of-line call is being made either way, there's a small performance cost for virtual dispatch that may be significant when calling trivially simple functions repeatedly in performance critical systems. (You have to read the per-object pointer to the virtual dispatch table, then the virtual dispatch table entry itself - means the VDT pages are consuming cache too.)
Memory usage: the per-object pointers to virtual dispatch tables may represent significant wasted memory, especially for arrays of small objects. This means less objects fit in cache, and can have a significant performance impact.
Memory layout: it's essential for performance, and highly convenient for interoperability, that C++ can define classes with the exact memory layout of member data specified by network or data standards of various libraries and protocols. That data often comes from outside your C++ program, and may be generated in another language. Such communications and storage protocols won't have "gaps" for pointers to virtual dispatch tables, and as discussed earlier - even if they did, and the compiler somehow let you efficiently inject the correct pointers for your process over incoming data, that would frustrate multi-process access to the data. Crude-but-practical pointer/size based serialisation/deserialisation/comms code would also be made more complicated and potentially slower.
Pay per use (in Bjarne Stroustrup words).
Seems like this question might have some answers Virtual functions should not be used excessively - Why ?. In my opinion the one thing that stands out is that it just add more complexity in terms of knowing what can be done with inheritance.
Yes, it's because of performance overhead. Virtual methods are called using virtual tables and indirection.
In Java all methods are virtual and the overhead is also present. But, contrary to C++, the JIT compiler profiles the code during run-time and can in-line those methods which don't use this property. So, JVM knows where it's really needed and where not thus freeing You from making the decision on your own.
The issues is that while Java compiles to code that runs on a virtual machine, that same guarantee can't be made for C++. It common to use C++ as a more organized replacement for C, and C has a 1:1 translation to assembly.
If you consider that 9 out of 10 microprocessors in the world are not in a personal computer or a smartphone, you'll see the issue when you further consider that there are a lot of processors that need this low level access.
C++ was designed to avoid that hidden deferencing if you didn't need it, thus keeping that 1:1 nature. Some of the first C++ code actually had an intermediate step of being translated to C before running through a C-to-assembly compiler.
Java method calls are far more efficient than C++ due to runtime optimization.
What we need is to compile C++ into bytecode and run it on JVM.
Considering the new CPUs with new instructions for moving and new memory controllers, if in C++ I have a vector of Derived objects where Derived is composed of virtual member functions, is this a good or a bad thing for the locality ?
And what if I have a vector of pointers to the base class Base* where I store references to derived objects that are 1-2-3 level up from Base ?
Basically dynamic typing applies to both cases, but which one is better for caching and memory access ?
I have a preference between this 2 but I would like to see a complete answer on the subject.
There is something new to consider as ground-braking from the hardware industry in the last 2-3 years ?
Storing Derived rather than Base * in a vector is better because it eliminates one extra level of indirection and you have all objects laid out «together» in a continuous memory, which in turn makes life easier for a hardware prefetcher, helps with paging, TLB misses, etc. However, if you do this, make sure you don't introduce a slicing problem.
As for the virtual dispatch in this case, it almost does not matter with an exception of adjustment required for «this» pointer. For example, if Derived overrides a virtual function that you are calling and you already have a pointer to Devied *, then «this» adjustment is not required, and otherwise it should be adjusted to one of the base class`s «this» value (this also depends on size of the classes in inheritance hierarchy).
As long as all classes in a vector have the same overloads, CPU would be able to predict what's going on. However, if you have a mix of different implementations, then CPU would have no clue as to what function will be called for every next object, and that might cause performance issues.
And don't forget to always profile before and after you make changes.
Modern CPU's know how to optimise data-dependent jump instructions, as well as it can for data dependent "branch" instructions - the processor will "learn" that "Last time I went through here, I went THIS way", and if it has enough confidence (gone through several times with the same result) it ill keep going that way.
Of course that doesn't help if the instances are a complete random selection of different classes that each have it's own virtual function.
Cache-locality is of course a slightly different matter, and it really depends on whether you are storing the object instances or the pointers/references to instances in the vector.
And of course, an important factor is "what is the alternative?" - if you are using virtual functions "correctly", it means that there is (at least) one less conditional check in a code-path, because the decision was taken at a much earlier stage. That condition would be (assuming the probability corresponds the same) to the branch probability of the decision, if you solve it by some other method - which will be at least as bad for performance as virtual functions with the same probability (chances are that it's worse, because we now have a if (x) foo(); else bar(); type scenario, so we first have to evaluate x then choose the path. obj->vfunc() will just be unpredictable because fetching for the vtable gives an unpredictable result - but at least the vtable itself is cached.
Just wondering whether dividing one class into several classes will reduce the efficiency of a program. In order to make my question clear, I give the following examples:
class OneClass
{
public:
Do_the_job()
{
Do_function1();
Do_function2();
Do_function3();
}
Do_function1();
Do_function2();
Do_function3();
variables_related_to_function1;
variables_related_to_function2;
variables_related_to_function3;
}
In this class, the functionality can be divided into three sub-functions, and they are in the same class. However, for the purpose of easy maintenance, I decide to make each sub-function a class, and the whole functionality is performed by combining three independent classes in one class:
Class OneClass
{
public:
Do_the_job()
{
class1.do_function1();
class2.do_function2();
class3.do_function3();
}
Class1 class1;
Class2 class2;
Class3 class3;
}
My question is that will the new implementation reduce the efficiency of the program. Thanks.
Probably not, and even if it does you're unlikely to notice.
The worst case for calling a method of another object is calling a virtual method via a pointer, which requires a vtable lookup to find the code to run, and that has to be done at runtime so it's not subject to inlining. But even that's pretty quick, and you're not going to notice it except in very specific situations.
Ordinary member functions on objects held by value is as fast as calling your own member functions.
Don't worry about things like this unless you can see that they're actually causing an issue. The impact of what kinds of function call you're making are negligible next to the potential speed problems caused by flawed algorithms, or even using postfix increment unnecessarily on some iterator classes.
Suggest you concentrate first of all on getting the logical design right, then think about these kinds of optimizations second. The kinds of optimizations that modern compilers and linkers will perform are quite impressive, and you should only worry about these kinds of performance issues after taking performance measurements / profiling.
In particular, modern linkers can do whole program optimization, when appropriate, which can essentially inline a method from another module, even if that module is in another statically linked library. So if the methods you're moving out are quite small, the executable code might be the essentially the same as the original.
The answer is "Probably Not". While I've never attempted to benchmark this, I do know that most developers write classes with cohesion in mind, rather than a specific number of functions. I tend to only allow 10 or so functions in my class. Any more complicated than that and I need to rethink my design.
That being said, if it is any slower, the difference is probably not discernible. Unless you're doing heavy polymorphic design with many calls to the vtable, you shouldn't notice a difference.
Even if you have multiple classes, invocation of a method still takes the same time as with only one class. So I think there's no reason why you shouldn't split up big classes and benefit from better readability and maintainability.
What really matters is if you're starting to use virtual methods, which requires a lookup for the address of the method at runtime (if the compiler can't resolve/inline it at compile-time). In this case, the invocation takes in the order of 3 instead of 1 machine code instructions.
If you're using dynamic dispatching AND multiple inheritance, you have an overhead in the order of 4-5 machine code instructions instead of one.
That said, I should mention that you probably won't feel a noticeable difference unless you have several thousand objects of a class. But then again you could start devirtualizing your classes to reduce the overhead.
Is there a significant performance hit if I keep adding member functions to a class? When I use the class, I may only use a couple of the member functions together at once so I could in theory split the single class into a number of smaller classes with fewer member functions. Do I take a big performance hit by cramming a lot of functions into the same class?
No, it doesn't matter.
But presence of lot of public` api indicates that you should make sure you are following the Single responsibility principle if you are trying to have a good design.
There should not be more than one reason for a class to change.
If you design adheres to that, then its all good and cramming a lot of functions to the class is not going to do any bad in terms of performance.
Some people might argue about performance hit if those functions are virtual however as long the purpose of those functions is to be overidden in the derived class then you should make them virtual, that is unless those functions are not being made virtual just for the sake of flexibility but on basis of a well thought design then go ahead and make them virtual.
Performance hits shouldn't be a concern its the price you pay for a functionality you want to have just that.
Also, Only profiling can actually give you accurate indications about performance bottle necks without it, what you get is speculations or guesses on the basis of experience which always might not be truly indicative.
The performance hit comes not from having lots of functions but having a deep hierarchy of functions calls to do a given task. Every function call results in
Pushing the pushing /saving current base pointer
Making saving current stack pointer and then making current stack pointer as the new base pointer.
Pushing the parameters on the stack.
Execute the function.
So e.g. If in sequence of execution if you end up calling 10functions you wind up stack 10 times and when the function(/s) is finished the stack has to be unwound.
Secondly there are gcc optimizations to reduce the cost of a jump to your function I the .Text e.g. By using an attribute called hot that improves the locality of such functions so that access of such functions is faster.
You always have to think about a function execution as *in the context of the thread executing it * so that you can identify various bottle necks and optimize them.
No, there shouldn't be and there wouldn't be any difference in binary size if you break up the class into smaller pieces. If you want to reduce binary size to only the function you call you can make your class a template.
I am considering using virtual inheritance in a real-time application. Does using virtual inheritance have a performance impact similar to that of calling a virtual function? The objects in question would only be created at start up but I'm concerned if all functions from the hierarchy would be dispatched via a vtable or if only those from the virtual base class would be.
Common implementations will make access to data members of virtual base classes use an additional indirection.
As James points out in his comments, calling a member function of a base class in a multiple inheritance scenario will need adjustment of the this pointer, and if that base class is virtual, then the offset of the base class sub-object in the derived class's object depends on the dynamic type of the derived class and will need to be calculated at runtime.
Whether this has any visible performance impact on real-world applications depends on many things:
Do virtual bases have data members at all? Often, it's abstract base classes that need to be derived from virtually, and abstract bases that have any data members are often a code smell anyway.
Assuming you have virtual bases with data members, are those accessed in a critical path? If a user clicking on some button in a GUI results in a few dozen additional indirections, nobody will notice.
What would be the alternative if virtual bases are avoided? Not only might the design be inferior, it is also likely that the alternative design has a performance impact, too. It has to achieve the same goal, after all, and TANSTAAFL. Then you traded one performance loss for another plus an inferior design.
Additional note: Have a look at Stan Lippmann's Inside the C++ Object Model, which answers such questions quite thoroughly.
Take a look at the following large scale experimental study published OOPSLA'96. I am copy pasting a bibtex entry, the abstract and a link to the paper. I would consider this the most comprehensive experimental study on the topic to date.
#article{driesen1996direct,
title={{The direct cost of virtual function calls in C++}},
author={Driesen, K. and H{\\"o}lzle, U.},
journal={ACM Sigplan Notices},
volume={31},
number={10},
pages={306--323},
issn={0362-1340},
year={1996},
publisher={ACM}
}
Abstract:
We study the direct cost of virtual function
calls in C++ programs, assuming the standard
implementation using virtual function tables. We
measure this overhead experimentally for a number of
large benchmark programs, using a combination of
executable inspection and processor simulation. Our
results show that the C++ programs measured spend a
median of 5.2% of their time and 3.7% of their
instructions in dispatch code. For “all virtuals”
versions of the programs, the median overhead rises to
13.7% (13% of the instructions). The “thunk” variant
of the virtual function table implementation reduces
the overhead by a median of 21% relative to the
standard implementation. On future processors, these
overheads are likely to increase moderately
http://www.cs.ucsb.edu/~urs/oocsb/papers/oopsla96.pdf
Are you sure you mean virtual inheritance? If so, it's identical to the cost of a normal virtual function call. The vtable chained search just follows a specified path.
You said that this was at startup. Your disk overhead (from simply loading your code into memory) is likely to require orders of magnitude more time than the half-dozen instructions or so for vtable lookups. I'd be somewhat surprised if you could profile this and detect a difference.
Without inspecting compilation or runtime details, based on my test using GNU C++17, accessing data member in virtual base class has no performance inpact.