c++ virtual function question

Started by
13 comments, last by warp X 17 years, 12 months ago
In my game I have code that calls virtual functions very much every frame. Would it be better/faster to call functions that are not virtual, but in them, test if there is a need for a virtual function call, and if is, then call? Sorry if this was not well put. Edit: What I mean is, that there isn't always a need. Actually mostly isn't.
"I got stuck between levels 4 and 5 and got into this strange place: warp X..."
Advertisement
Sounds to me as though that would be just as slow (maybe more so) than just calling a virtual method.
____________________________________________________________Programmers Resource Central
Test it, but maybe your overhead for testing is much more expensive then just calling the virtual function. It's slower to call a virtual function but it's far from slow.
I don't think the improvement is worth the effort.
Virtual calls are part of OO paradigm. If you find they are a problem (performance bottleneck), change the design not to use the OO aproach (use objects, but don't use inheritance).

Do not change anything at all, unless you have a performance problem. Just because something is used a lot, it makes no difference if it does not slow you down.

Unless virtual function calls are posing a slowdown, and they shouldn't be, then don't bother. This is premature optimisation, avoid it.

The test would probably end up being about as expensive anyway, due to the overhead of maintiaining information about which functions are available. You are probably going to be accesing an object like so:

if( object->hasFunc ){    object->func();}


as opposed to

object->func();

My advice would be just to call it directly.
As the AP said, don't test. It'll be even slower than calling the function. Virtual functions do have an overhead, but it's minimal; just two pointer dereferences usually (I think...).

EDIT: Way to slow [smile]
I wouldn't worry about it. You won't be able to "test if a virtual function call is needed" in any feasible way that will be faster than the compiler actually invoking the virtual call (you'll have to use dynamic_cast or typeid prior at the call site and that will be slower than the table lookup the compiler will do to find the correct virtual function and once you determine if the type wouldn't actually 'need' the vtable lookup you'll have to do a bunch of extra mucking about to get the compiler to not perform the lookup; its not worth it).

If you've profiled and determined that the virtual dispatch mechanism is actually taking up a signifigant bit of time (which I doubt) you may want to look into methods to reduce the number of virtual calls you make. But again, I really doubt its going to be a speed concern unless you are working on a very, very limiting platform.

EDIT: Way too slow :(
Ok, thanks for advice. There is, however performace problems in my application. I am making a bird-view 2D war game with soldiers, tanks, etc. It is getting a bit slow, when you have tens and tens of soldiers there, and you got to detect collisions for them and for the projectiles they shoot. You also have AI routines for them that detect the closest enemy to fire at. So there is lots going on, lots of iterating through all the game objects. I did limit the collision detection so that it is not called on every frame anymore, which helped a bit. I am using collisionspheres.

In the collision detection routine you have to consider how many collisionspheres an object has, because it might have many.

A short story long, sorry for this, but don't read if you don't want to:

I did already this kind of optimization:

I had code like this:





virtual int GameObject::getCollisionSphereCount() { return 1; }
int Tank::getCollisionSphereCount() { return 2; }

I changed it into this:

int GameObject::collisionSphereCount;
GameObject::GameObject() { collisionSphereCount = 1; }
Tank::Tank() { collisionSphereCount = 2; }
int GameObject::getCollisionSphereCount() { return collisionSphereCount; } //*

//*this is in the gameobject.h -file so it's inline and all, right?

So this is a fair optimization, I think, right?




But, here's an other case I'm wondering if I should do:

I have code like this:

class GameObject { ... };
class Tank : public GameObject { ... };

float GameObject::x;
float GameObject::y;
struct CollisionSphere { float x, y, radius; }
virtual ColisionSphere GameObject::getCollisionSphere(int index = 0)
{
CollisionSphere cs;
cs.x = x;
cs.y = y;
cs.radius = collisionSphereRadius; //defined somewhere....
return cs;
}
collisionSphere Tank::getCollisionSphere(int index = 0)
{
if (index == 0)
return getCollisionSphere1(); //defnied somewhere...
else
return getCollisionSphere2(); //defnied somewhere...
}



Should I do this like this:

virtual CollisionSphere GameObject::getDynamicCollisionSphere(int index) { ... }
CollisionSphere Tank::getDynamicCollisionSphere(int index) { ... }
ColisionSphere GameObject::getCollisionSphere(int index = 0)
{
if (collisionSphereCount > 1)
getDynamicCollisionSphere(index);
else
{
CollisionSphere cs;
cs.x = x;
cs.y = y;
cs.radius = collisionSphereRadius; //defined somewhere...
}
return cs;
}

Edit: added class hieratchy desciription
"I got stuck between levels 4 and 5 and got into this strange place: warp X..."
Profile. There's no point in blindly optimizing in the hope that what you're doing is improving performance. What IDE are you using? There's a few profilers about for Visual C, or you could write your own functions into your code.

I very much doubt that the virtual functions are your problem if you only have 10 units. If you had 1000 or more, then maybe the virtual function overhead would start to become a problem.

I'd recommend partitioning your map up using a quadtree or octree or some other spatial partitioning. After you've profiled your code and determined that the collision detection is a problem.
You are right. It might be just waste of my time.
I am using Visual Studio .net 2003. Ok, I should learn that profiling thing, I haven't used that.

I have not decided yet what is the maximum number of units on screen. It will, of course, be affected by the overall performance. I hope there could be lots of units at the same time.

That space partitioning sounds interesting, but does it make a difference in a 2D game?

I'm using lots of math functions like pow, sqrt, sin, cos, etc. I have read that these might be slow. Should I consider optimizing the math? I'm for example determining object distances with pythagoras like this: distance = sgrt(pow(a, 2), pow(b, 2)).

Edit: thank you for banging some wisdom into my thick skull.
"I got stuck between levels 4 and 5 and got into this strange place: warp X..."

This topic is closed to new replies.

Advertisement