Cameron Wilby
Cameron Wilby

Reputation: 2310

Which is quicker/more efficient?

Currently learning about efficiency in C++ and wondered about the efficiency of returning parameters in methods.

Imagine a Vector3f class with an add method.

Code One:

Vector3f Vector3f::add(const Vector3f &rhs) const {
    Vector3f result;
    result.x(x() + rhs.x());
    result.y(y() + rhs.y());
    result.z(z() + rhs.z());
    return result;
}

Code Two:

Vector3f Vector3f::add(const Vector3f &rhs) const {
    return Vector3f(
                x() + rhs.x(),
                y() + rhs.y(),
                z() + rhs.z());
}

I know that the second code segment is more efficient, and I was hoping someone could give me a definitive answer as to why. I'm sure it's something to do with temporary objects.

Upvotes: 2

Views: 310

Answers (3)

Mike Dunlavey
Mike Dunlavey

Reputation: 40649

It's fine to wonder how the compilers do things, but I assume you understand there are almost always bigger "fish to fry".

It seems to me lots of people get their ideas about performance from teachers and authors who haven't had much experience with big gnarly real software. I don't know how else to explain the concentration on micro-issues, and that people don't seem to know when they are guessing, even if the guesses are educated.

So, FWIW, here are some common conceptions about performance.

Upvotes: 0

xtofl
xtofl

Reputation: 41509

Actually, it has more to do with initialization: when you 'default construct' your Vector3f result, the x, y, z members will be initialized. You don't always control the cost of that, especially with 'heavy' members.

Calling a constructor with all member values allows the object to initialize it's members first time right.

But if you really want to save some intermediate steps, you can create a mutator on the class Vector3f, eliminating the need for a temporary:

class Vector3f {
   ...
   Vector3f& operator+=( const Vector3f& other ) {
      x += other.x;
      y += other.y;
      z += other.z;
      return *this;
   }
};

and use it like

Vector3f a( 1,2,3 );
a += Vector3f( 0,0,1 );

Upvotes: 1

Marcelo Cantos
Marcelo Cantos

Reputation: 185852

It probably has to do with the return-value optimisation (RVO). Because the second form constructs the object as it returns it, the compiler is allowed to (and usually will) skip the copy-constructor by constructing the object directly in the caller's context.

The first form can also be optimised in similar fashion, but I've often seen compilers optimise the latter and not the former.

Upvotes: 5

Related Questions