Virtual still the bad way ?

Started by
21 comments, last by Shannon Barber 11 years, 4 months ago
If you have legitimate reason to be worried about the performance costs of run time polymorphism, Agner Fog has a section in his free guide to Optimizing C++ that describes how to do compile time polymorphism. You sacrifice a bit of readability for that possible benefit in performance though. Section 7.28 - "Templates" describes this. That pdf is an interesting thing to read if you ever have bits of free time scattered through your day that you need to make use of.
Advertisement
I just want to say, each and every person so far has posted "true" statements ... but most of the posters have made a simple scientific / engineering question into a religious idea when it has no reason to be.

1. A language without "virtual" would not be very good for OO. I agree with this, on the grounds that dynamic dispatch / run-time polymorphism is one of the key ideas for the standard type of OO programming practiced today, from Smalltalk based roots. There are however other types of "OO", including the template / compile time version used in Advanced Template Metaprogramming and Modern C++ Design.

More people need to realize that programming languages exist to make life easier for the programmer to express a desire at programming time ... not to make any certain set of things happen at run-time unless they are needed to accomplish the desired result. Hence the rise of declarative concepts in recent years, which make the compiler and run-time work harder for the programmer.

2. Use virtual when you want run-time polymorphism or dispatch. Absolutely agree. This very useful keyword exist almost exclusively for this very purpose. When this is what you want, only very specialized alternatives can give any increased performance over the very simple virtual table. Examples of slightly "specialized" optimizations were already mentioned earlier in this thread ... such as polymorphic / virtual factories, which then do NOT use virtual method invocations internally ... so you pay the cost only during initialization (where it doesn't matter and isn't repeated), instead of during every method call of every object in your game loops.

3. The cost of virtual is "just" an extra indirection - function lookup. True. But "just" can be misleading. It is no more, nor less than this.

4. The cost of virtual is insignificant. Not always true. If you are trying to write a modern game engine, you simply cannot afford the cost of virtual function call on every function. It would be impossible to write a highly oo, completely dynamic game engine which tens-of-thousands of object running every frame with uncessary indirections at every level. When used "correctly" or at least either "when necessary", "when appropriate" or "sparingly" ... then virtual is great. When used for "no reason", "by default", "without consideration" or "excessively" ... virtual function call costs can actually account for a large percentage of your total performance cost - especially if also mixed with deep abstract object trees.

4. Inheritance implies virtual functions. Not at all true. virtual functions imply inheritance but NOT the other way around. Many many programming problems use inheiritance, but not run-time polymorphism.

I don't advocate avoiding virtual. In fact I use it quite heavily. And when prototyping I actual apply it "by default" on my prototype classes. But as your design solidifies, you realize a large set of methods has no reason to be virtual - UNLESS you are releasing BINARY class libraries to be consumed in unexpected ways by THIRD PARTIES who do NOT have access to your source code. That is the ONLY case where unknown use-cases dictate extra virtuals where not "needed" by existing client code.

Even more than virtuals I do most my programming in C# / .NET with all of its costs ... but when I have to tune the performance of an audio mixing library, or reduce the footprint / performance profile of some asynchronous networking code - I go to C++, and I use a "proper" design for the problem ... not just throw abstractions and features at it and hope performance just happens to be "good enough".
You just have to understand what you are doing.
For a render you will not be passing the data directly to the functions, you will be passing pointers if-not handles to the methods.
So structured-coding overhead is guaranteed.
If you start creating function-pointers to code something up, you may-as-well have just used virtual functions.
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara

This topic is closed to new replies.

Advertisement