Boost logo

Boost :

From: Terje Slettebø (tslettebo_at_[hidden])
Date: 2002-10-15 00:00:30


>From: "Pavel Vozenilek" <pavel_vozenilek_at_[hidden]>

> "Terje Slettebø" <tslettebo_at_[hidden]> wrote in message
> news:03b201c2722f$339fb850$60fb5dd5_at_pc...
> > Sorry, this should be:
>
> > inline Test operator+(const Test &t1,const Test &t2)
> > {
> > return Test(t1)+=t2;
> > }
>
> > The result is the same, though, as it inlines it, anyway.
> >
> operator+() can be implemented like described in
> http://www.semantics.org/gotchas/gotcha36.pdf (Stewe Dewhurst Gotcha#36).
> Modified test code is bellow: it uses private constructor and avoids any
> copying in your case. The constructor can be tuned for this specific
> operation.
>
> (I tried your example on Intel C++ 7.0beta and result is code without any
> rep movsb at all.)

Yeah, but that would be cheating. :) In this case, only the "num" member of
Test is assigned to or copied, not "array", which makes it an incomplete
operator+(), and operator+=(). In real code, it would likely need to assign
to both members, in operator+=(), which could be called from operator+().

In other words, getting the wrong result fast is never a bargain. :)

The Test class was only meant as an example, and the operator+=() is
incomplete. I didn't do anything with "array" there, to not make the code
longer. "array" is just copied implicitely to the target object. In a real
operator+=(), you might have code which added the source and target arrays,
and then your "optimisation" couldn't be used.

In order to do the right thing, the "computational constructor" you used
would need to do a complete addition (or if just copy is chosen for this
example):

Test(const Test& lhs, const Test& rhs) : num(lhs.num + rhs.num)
{
  std::memcpy(array,lhs.array,1024*sizeof(int));
}

And then we're back to having a copy in the code, after all.

I agree with you that your solution is more efficient for the given example,
but that's just because the example was not meant to be a realistic one, as
it didn't access "array" in the operator+=(), which meant you could omit the
copying of it. However, as mentioned, that's unlikely in real code.

The use of such "computational constructors" is a good point, however. Where
possible, it can enable optimisation using RVO, if NRVO isn't available. So
that is definitely a valid point.

> operator+=() cannot be optiomized this way and should be used for testing.
>
> -------------------------------------------------------------
> class Test
> {
> private:
> // special private constructor to support operator+()
> friend Test operator+(const Test& lhs, const Test& rhs)
> Test(const Test& lhs, const Test& rhs) : num(lhs.num + rhs.num) {}
>
> public:
> Test(int n) : num(n) {}
>
>
> Test &operator+=(const Test &other)
> {
> num+=other.num;
>
> return *this;
> }
>
> int num;
> int array[1024]; // Just so that copying shows up
> };
>
>
> Test operator+(const Test& lhs, const Test& rhs)
> {
> return Test(lhs, rhs); // here's the trick
> }

Regards,

Terje


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk