iseletsky
iseletsky

Reputation: 653

C++ Classes versus utility functions

So I may want various functions that operate on a line:

inline float yIntercept(const vec2& ptA, const vec2& ptB, float x);
inline float xIntercept(const vec2& ptA, const vec2& ptB, float y);
inline bool lineIntersection(const vec2& ptA0, const vec2& ptB0, const vec2& ptA1, const vec2& ptB1);

The functions takes 2 points for each line representing the line.

Or I can write a line class that has those 2 points and various useful line related methods.

struct Line {
    ... stuff

    inline float xIntercept(float y);
    inline float yIntercept(float x);

    inline bool lineIntersection(const Line& other);

    vec2 m_point[2];
};

One thing I was thinking about is performance of creating an instance of this line class every time I need to call one of these functions just given 2 points.

I may be operating on a point list representing a polygon and don't actually have any line objects instantiated.

At any time I may either call

yIntercept(somePointA, somePointB, 3.0f);

Or

Line(somePointA, somePointB).yIntercept(3.0f);  //I think this would compile

I like the idea of having classes for these kinds of things rather than C style functions, but I was wondering if there's some performance penalty of creating an instance of the class like this rather than just passing the points right into a function. Maybe the compiler does some optimization?

Upvotes: 3

Views: 887

Answers (2)

Drew Dormann
Drew Dormann

Reputation: 63775

Choose your solution based on other factors. Effort involved or readability, perhaps.

The reason to take this approach is because you are choosing between these two scenarios:

  1. Incurring the extra work of creating Line objects.
  2. Incurring the extra work of passing more parameters to your functions.

The compiler can do optimizations on either 1. or 2. And it might. Or not. And it might help. Or not.

See this article to learn more about optimization decisions like yours. The author's okay.

http://www.codinghorror.com/blog/2009/01/the-sad-tragedy-of-micro-optimization-theater.html

Upvotes: 1

Mats Petersson
Mats Petersson

Reputation: 129364

One thing I was thinking about is performance of creating an instance of this line class every time I need to call one of these functions just given 2 points.

If that really is a problem in your application, then you are probably "doing it wrong". What I mean by that is that, done right, the code to create this object should be very lightweight. And even then, would you really need to create a lot of these object - do the "things" that make up the lines not presist over time, so the struct Line could be made part of the overriding object in some way or another.

For example, in a polygon, you could make Line objects from your pointlist, and keep those around.

I would also start by writing a generic, well working codebase, then optimise when everything is working. If you have to rewrite something, so be it. Hopefully, you've made your interfaces sufficiently generic that you don't have to rewrite too much OTHER code.

And whenever performance optimising, make sure you measure, measure again, and note what you've done to change it. I've sometimes had several hundred lines in spreadsheets with "Tried modifying X", "Used clever trick in function A", and the results - sometimes the result is "lost 5%" (or "lost 500%"), but at least you then know what the result is. Using "I think the compiler will do this" requires A LOT of experience with any given compiler.

Upvotes: 1

Related Questions