Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

A. Buza

virtual funcs... performance penalty?

This topic is 6410 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I was just curious as to any performance penalties incurred from using virutal and pure virtual functions when creating derived classes.

Share this post


Link to post
Share on other sites
Advertisement
Yes, there is a performance penalty (pointer to a function call).
Yes it is negligible in most every circumstance.

Basically, unless you''re doing a virtual function call in one of your inner most loops, you shouldn''t worry about it.

If you do still worry about it, there are ways to get some compilers to inline virtual functions. There was a Tip of the Day describing the basics of this on flipcode (www.flipcode.com) not too long ago...

You can also find information here:

http://msdn.microsoft.com/msdnmag/issues/0600/c/c0600.asp

Share this post


Link to post
Share on other sites
Don''t worry at all. I''ve looked at the code produced by my compiler, and here''s the difference:

Non-virtual:
call ABCD;

Virtual:
call [0123];

That''s it! A memory reference, which (on a 386) take the clock count up to 10, instead of 7. Oh no.



David Owen

Share this post


Link to post
Share on other sites
Actually, there''s a few more penalities than indicated.

First off, every instance of a class that has virtual functions has as an implicit member variable that is a pointer to the vtable for the function. So on an x86, that would double the memory required for a class that has only one variable. This leads to increased cache misses, memory motion costs, etc. Also it adds an mov instruction to the constructor for the class. For most classes that you use virtual functions for this isn''t a big deal, but it''s a good reason to never make a linked list node with a virtual function.

Second the function invocation code is slightly more complicated than previously indicated. Let''s say I have a class like so:

class Base {
virtual int Func1(int a);
virtual int Func2(int a);
int Func3(int a);
};
Base * b;

Then
b->Func3(5);
would produce the following assembly (assuming eax was already loaded with b:

push 5
push eax
call @@Base@Func3$qi
add esp,8

on the other hand
b->Func2(5);
would produce the following assembly:

push 5
push eax
mov edx,dword ptr [eax]
call dword ptr [edx+4]
add esp,8

There is one additional instruction, and two additional pointer indirections, one of which is indexed. Again not a big deal, but you can see how in a tight loop it could be murder.

Share this post


Link to post
Share on other sites
For those of you interested, I ran a simple performance test.

Basically I created an instance of a leaf class that was the 5th deriviation from a base class. This leaf class contained an empty virtual function and an empty normal function. I created an instance of the class as a pointer, and ran both functions in a loop 1 million times.

Virtual function time: 0.011080 seconds
Normal function time: 0.008243 seconds

FYI, If it''s a normal variable then the time is exactly the same.

My compiler: VC6


- Houdini

Share this post


Link to post
Share on other sites
How do you look at the compiler output/browse it/find certain sections?

By ''virtual'' function, do you mean one that has overriden a virtual one, but is no longer declared as virtual anymore??? If I override in the first child class down, can I override again in the next one down, even if the one in the first one down isn''t marked as virtual over again. Are all versions ''virtual''...?

Thanks

Share this post


Link to post
Share on other sites
If function declared as virtual in base class, it will be virtual in all derived class, independly you write ''virtual'' world in derived class or not

Share this post


Link to post
Share on other sites
The big performance penalty is when you use a base class pointer to a derived class and call an overridden function (all pure virtuals, and some virtuals).

Then again, the "big" performance penalty made by code about 200% slower on a 33MHz machine... I suppose it would only be about 6% slower on a 1000MHz machine... but still, that''s 6%!

Share this post


Link to post
Share on other sites
Yes, but do you think that most of the processing power your game takes up is in function calls? It''s spent displaying graphics and calculating AI. In my tests (using a base class pointer to a derived class and calling an overridden function) you lose a whole 0.003 seconds (3 milliseconds) for every 1 million virtual function calls.

- Houdini

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!