-1

I have some trouble. While planning my program, I consider 2 versions:

  1. Use static methods in classes with additional parameter (pointer to copy of a class).
  2. Use virtual methods (vtable)

What is faster? Why?

Edit: I need to make next algorithm: array should be storing pointers to method of different classes (they meet diff. game objects), for example, method Draw().

The main task is storing and calling methods of different classes.

Bowdzone
  • 3,827
  • 11
  • 39
  • 52
  • 3
    Use what makes sense in your design. Don't try to emulate the `this` pointer. Consider speed (w.r.t. this question) when your program is working correctly. – Christian.K Mar 02 '12 at 12:09
  • 4
    What makes you think you can implement virtual method dispatch better than your compiler vendor? What makes you think that the performance of virtual method dispatch is important to you? – David Heffernan Mar 02 '12 at 12:11
  • speed and performance depends on how and where you use refre this http://stackoverflow.com/questions/113830/performance-penalty-for-working-with-interfaces-in-c#answer-114000 – sandeep Mar 02 '12 at 12:18
  • 2
    Wow. This is one of the most egregious cases of [premature optimization](http://en.wikipedia.org/wiki/Program_optimization#When_to_optimize) I have *ever* seen. Virtual methods are the very core of C++. This is the tiniest of microoptimizations, to let it dictate the class model is insane. – David Schwartz Mar 02 '12 at 12:19
  • "What is faster ?" Nothing because "fast" is an attribute that applies to the execution of your code and you have no code yet, which makes the question irrelevant. Write your code cleanly first, measure and then, only if there are **real** performance issues, optimize. – ereOn Mar 02 '12 at 12:25
  • @David Heffernan and ereOn, I have code. Now I rewriting my code from zero. In 3D graphics speed is very important thing! – WORLD_DYNAMIC_USER Mar 02 '12 at 12:49
  • 2
    @WORLD_DYNAMIC_USER no one is disputing that speed is important in some contexts. You might have missed a bit in ereOn's comment: *write code, **measure**, optimize*. What makes you think that it is the dispatch what is killing your performance? And even if it is, how much do you think you can squeeze out by changing the dispatch (and compare that with the cost of the rewrite and maintenance) – David Rodríguez - dribeas Mar 02 '12 at 13:18
  • @WORLD_DYNAMIC_USER Has it occurred to you that your compiler vendor's might already have optimised virtual method dispatch? And if you are so obsessed with optimising performance at this stage, why not code in C or asm? – David Heffernan Mar 02 '12 at 14:01
  • 1
    The overhead of virtually calling a high-level function such as `Draw()` shouldn't have any noticable impact at all on performance, since you only do that once per frame per object. – molbdnilo Mar 02 '12 at 15:34

2 Answers2

2

At this point, you probably shouldn't be thinking about micro-optimisations at all - focus on choosing efficient algorithms, and making your code clear and correct; then identify any bottlenecks that prevent it from performing as required. Having said that, here are some thoughts in the unlikely event that you do find that virtual dispatch becomes an issue.

The two are not equivalent - the first (if I understand what you're saying) is trying to emulate a non-virtual function by explicitly passing a this-like pointer to a static function, and is likely to be exactly as fast as the non-static equivalent. It will behave differently to a virtual function, and so can't be used if you need virtual dispatch.

A non-virtual function will (almost certainly) be a bit faster than a virtual function - it's more likely to be inlined, and if not inlined it can be called directly rather than looked up at runtime. Therefore, only declare functions virtual when you need virtual dispatch.

In extreme circumstances, you might be able to save a level of indirection over virtual functions, by storing function pointers in the object rather than using the compiler-generated virtual dispatch. You should only do this as a last resort, if you find that virtual dispatch is a serious bottle-neck, and you can't sensibly redesign your algorithm to avoid it.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • I need to make next algorithm: array should storing methods of different classes (they meet diff. game objects), for example, method Draw(). I found two ways to get it: static functions and virtual functions. – WORLD_DYNAMIC_USER Mar 02 '12 at 12:45
  • 1
    On the last point, note that unless you have a huge amount of types, the vtables will be cached in the processor, the extra level of indirection will most probably have very limited effect, and it is actually quite simple to measure. I bet that the effect on the performance is below 1% (much below that if the functions do any actual work) – David Rodríguez - dribeas Mar 02 '12 at 13:23
  • Well, "the vtables will be cached in the processor, the extra level of indirection will most probably have very limited effect", than I will use "emulating" a _this_-pointer. Thanks :) – WORLD_DYNAMIC_USER Mar 02 '12 at 14:17
0

First, virtual functions and what you are proposing have different semantics. If you need different behavior because you have different types of objects, then it's highly unlikely that you can do better than the compilers implementation of virtual functions. If you don't need it, then just don't declare the function virtual.

And don't worry about the performance issue until you know it is one.

If, after getting the code to work, you do find performance issues due to virtual function calls (usually because the compiler can't inline the function, so you loose all of the optimizations which would follow inlining), you can, punctually, avoid the virtual function cost if you design the class correctly. Supposing the function in question is f():

class Base
{
    virtual void doF() = 0;
public:
    void f() { doF(); }
};

class Derived : public Base
{
    virtual void doF() { f(); }
public:
    void f() { /* ... */ }
};

If you do this, and you have, for example, a tight loop where you're constantly calling f() on the same object, you can do something like:

void
tightLoop( Base& object )
{
    Derived& o = dynamic_cast<Derived&>( object );
    for ( /* ... */ ) {
        o.f();
    }
}

If you do this, of course, tightLoop can only be called with an object which is actually Derived.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • "First, virtual functions and what you are proposing have different semantics." - Why? For example, we have 2 types: bottle and door. I can make the parent class with virtual method "Draw()". In array I add the pointer to 1 copy of child class, who overload this method. And Draw() I can call "((Parent *)ptr[i]))->Draw()". And this isn't depend on child class! – WORLD_DYNAMIC_USER Mar 02 '12 at 12:55