Archived

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

C++ class constructor chewing my framerate.

This topic is 5148 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 did some profiling on my physics engine, and noticed that my 3d-vector''s constructor is hogging 15% of the performance. It gets called a lot, as all my vector operators use it to return the result. This is the constructor:
CVector(float X, float Y, float Z) : x(X), y(Y), z(Z) {} 
And the plus-operator, as an example:
CVector operator+(const CVector& V) {
  return CVector(V.x+x, V.y+y, V.z+z);
} 
Naturally vector addition, multiplication and all the others are called enormously often, but spending 15% on the constructor brings tears to my eyes. Am I doing something wrong here?

Share this post


Link to post
Share on other sites
No, not really. But turn off the exceptions if you can. The compiler won't be able to optimize temporaries away from the operators as easilly, if you have them on. I might be wrong though, it's a couple of years since I looked at that. And vc++ 7.1 probably optimize better. You could also use the += operator instead, to avoid temporaries.

Aditionally, make sure that no variables are initialized in the default constructor. Then you can make an Add function and use it like this.

CVector result;
result.Add(vec1, vec2);


And you won't spend extra time copying things around, or initialize variables that are not necessary to initialize. You could also extend this, like adding 3 vectors, multiplying and then adding, and things like that.

[edited by - fredizzimo on November 12, 2003 6:41:36 PM]

Share this post


Link to post
Share on other sites
Partial Template Specialisation can help, but chances are this isn''t an option. It''s hard to implement, not supported by all compilers, bloats, ...

Anyway, my version, based on

template class t_vec { ... };

quickly grew into a complete nightmare, especially when magnitude etc was implemented.

Google it.

Wizza Wuzza?

Share this post


Link to post
Share on other sites
quote:
Original post by Chris Hare
Partial Template Specialisation can help, but chances are this isn''t an option. It''s hard to implement, not supported by all compilers, bloats, ...

Anyway, my version, based on

template class t_vec { ... };

quickly grew into a complete nightmare, especially when magnitude etc was implemented.

Google it.

Wizza Wuzza?


Could you explain how partial template specialization could help, when there''s only going to be floats in the vector, and always three values. If one of those varies, then maybe. Templates can speed up abitary sized matrices though.

Share this post


Link to post
Share on other sites
I wrote a ''strange'' template class named IperPoint (and IperRect) to implement, with the same code, Point2D,3D,4D with real and integer...and my class Vector is also derived from it so I can pass a Vector as a 3D Point.
But to optimize code I override every function in Vector to avoid an extra loop (for every template N coordinate)...

No, you are doing well...you can use inline for the simplest functions (to avoid stack argument copy). For example use inline for ctors, operators +,-,+=,-=...

Share this post


Link to post
Share on other sites
One idea would be to return some sort of a holder that acts as a temporary. i.e:


struct holder
{
int x_, int y_;
};

struct Vector
{
Vector(int x, int y) : x_(x), y_(y)
{
}

Vector(const holder& h) : x_(h.x), y_(h.y)
{
}

holder operator+(const Vector& v)
{
holder h = {x_+v.x_, y_+v.y_};
return h;
}

friend holder& operator+(holder& h, const Vector& v);

private:

int x_, y_;
}

holder& operator+(holder& h, const Vector& v)
{
h.x_ += v.x_;
h.y_ += v.y_;
return h;
}


I did a small test and it reduces the number of temporary objects being created: g = a * b + c - d * e + f resulted in 2 ctor calls, compared to 5 when doing it the normal way. Anyways, I''m no wiz at this and I only have a non optimizing compiler, so it''s very unsure that it will actually result in better performance. But perhaps it might be worth a try.

Share this post


Link to post
Share on other sites
I'm just guessing, but perhaps the reason your ctor is consuming so much % is because you use it to implement your operators.

You are profiling release builds correct? Often ctor's are eliminated.

Do you have a default, do-nothing ctor for CVector?

[edited by - Magmai Kai Holmlor on November 12, 2003 9:27:38 PM]

Share this post


Link to post
Share on other sites
Thanks for all the replies. I am profiling the release build, and I do have an empty constructor "CVector(){}". The constructor itself doesn't seem to be very slow, it just gets called insanely lot. Tried to clean up some of the more unneeded constructor calls from my inner loops, and it reduced the amount a bit. Still gets called 2 million of times in a 5-second run.

And thanks for the article link, David.

[edited by - juuso on November 13, 2003 3:19:16 AM]

Share this post


Link to post
Share on other sites