www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Getting rid of unnecessary temporary objects in calculations? (Suggestion)

reply Kristian <kjkilpi gmail.com> writes:
Lets consider the following:

class Foo {
     Foo clone() {
         Foo ret =3D new Foo;

         ret.val =3D val;

         return(ret);
     }

     Foo opAdd(Foo Obj) {
         return(clone() +=3D Obj);
     }

     Foo opAddAssign(Foo Obj) {
         val +=3D Obj.val;
         return(this);
     }

     int val;
}

Usually 'opXxx' and 'opXxxAssign' are closely related: 'a =3D a + b' <->=
 'a  =

+=3D b'. It would be very strange if that were not true.

So, if a class has 'opXxx'/'opXxxAssign' it normally it has also  =

'opXxxAssign'/'opXxx', and a clone function.

The compiler could then automatically generate 'opXxx' functions if a  =

class has a standard clone operator, e.g. 'opClone'. Of course, you can =
 =

easily mixin the 'opXxx' functions by yourself. But lets consider the  =

following next:

     Foo a, b, c, d;

     a =3D b + c + d;

A temporary object is created here two times. One should be sufficient.

For example, you have a HugeMatrix class you use calculations, it gets  =

cloned more than once, which is unnecessary. That can prevent operators =
to  =

be used at all (too much time would be spend on cloning).

What if compiler assumes that the 'opXxx' operators always return  =

temporary objects? Then "a =3D b + c + d;" would be read as:

     a =3D b.opAdd(c).opAddAssign(d);

That's efficient.


Now, what if we get rid of the 'opXxx' operators altogether?

If a class has 'opClone', then the class is treated as a value type:  =

statements are compiled with the 'opClone' and 'opXxxAssignment' operato=
rs  =

only. For example, "a =3D b + c + d;" will be read as:

     a =3D b.opClone().opAddAssign(c).opAddAssign(d);

Then you could always use operators freely and there would be no redunda=
nt  =

operator functions (e.g. 'opAdd' *and* 'opAddAssign'). Of course, that  =

would also enforce 'a =3D a + b' <-> 'a +=3D b' to be true always, but I=
 think  =

so it should be.


And if there will be a copy/clone operator, lets say '<-', then

     a <- b;
     a <- b + c;

would be, of course, read as:

     a <- b;     //=3D=3D a =3D b.opClone();
     a =3D b + c;  //=3D=3D a =3D b.opClone().opAddAssign(c);
Oct 24 2006
parent reply Don Clugston <dac nospam.com.au> writes:
Kristian wrote:
 
 Lets consider the following:
 
 class Foo {
     Foo clone() {
         Foo ret = new Foo;
 
         ret.val = val;
 
         return(ret);
     }
 
     Foo opAdd(Foo Obj) {
         return(clone() += Obj);
     }
 
     Foo opAddAssign(Foo Obj) {
         val += Obj.val;
         return(this);
     }
 
     int val;
 }
 
 Usually 'opXxx' and 'opXxxAssign' are closely related: 'a = a + b' <-> 
 'a += b'. It would be very strange if that were not true.
 
 So, if a class has 'opXxx'/'opXxxAssign' it normally it has also 
 'opXxxAssign'/'opXxx', and a clone function.
 
 The compiler could then automatically generate 'opXxx' functions if a 
 class has a standard clone operator, e.g. 'opClone'. Of course, you can 
 easily mixin the 'opXxx' functions by yourself. But lets consider the 
 following next:
 
     Foo a, b, c, d;
 
     a = b + c + d;
 
 A temporary object is created here two times. One should be sufficient.
 
 For example, you have a HugeMatrix class you use calculations, it gets 
 cloned more than once, which is unnecessary. That can prevent operators 
 to be used at all (too much time would be spend on cloning).
 
 What if compiler assumes that the 'opXxx' operators always return 
 temporary objects? Then "a = b + c + d;" would be read as:
 
     a = b.opAdd(c).opAddAssign(d);
 
 That's efficient.
 
 
 Now, what if we get rid of the 'opXxx' operators altogether?
 
 If a class has 'opClone', then the class is treated as a value type: 
 statements are compiled with the 'opClone' and 'opXxxAssignment' 
 operators only. For example, "a = b + c + d;" will be read as:
 
     a = b.opClone().opAddAssign(c).opAddAssign(d);
 
 Then you could always use operators freely and there would be no 
 redundant operator functions (e.g. 'opAdd' *and* 'opAddAssign'). Of 
 course, that would also enforce 'a = a + b' <-> 'a += b' to be true 
 always, but I think so it should be.
 
 And if there will be a copy/clone operator, lets say '<-', then
 
     a <- b;
     a <- b + c;
 
 would be, of course, read as:
 
     a <- b;     //== a = b.opClone();
     a = b + c;  //== a = b.opClone().opAddAssign(c);
Take a look at: http://d.puremagic.com/bugzilla/show_bug.cgi?id=124 which also deals with cases like a = b - a;
Oct 24 2006
parent Kristian <kjkilpi gmail.com> writes:
On Wed, 25 Oct 2006 09:33:04 +0300, Don Clugston <dac nospam.com.au> wro=
te:

 Kristian wrote:
  Lets consider the following:
  class Foo {
     Foo clone() {
         Foo ret =3D new Foo;
          ret.val =3D val;
          return(ret);
     }
      Foo opAdd(Foo Obj) {
         return(clone() +=3D Obj);
     }
      Foo opAddAssign(Foo Obj) {
         val +=3D Obj.val;
         return(this);
     }
      int val;
 }
  Usually 'opXxx' and 'opXxxAssign' are closely related: 'a =3D a + b'=
<-> =
 'a +=3D b'. It would be very strange if that were not true.
  So, if a class has 'opXxx'/'opXxxAssign' it normally it has also  =
 'opXxxAssign'/'opXxx', and a clone function.
  The compiler could then automatically generate 'opXxx' functions if =
a =
 class has a standard clone operator, e.g. 'opClone'. Of course, you c=
an =
 easily mixin the 'opXxx' functions by yourself. But lets consider the=
=
 following next:
      Foo a, b, c, d;
      a =3D b + c + d;
  A temporary object is created here two times. One should be sufficie=
nt.
  For example, you have a HugeMatrix class you use calculations, it ge=
ts =
 cloned more than once, which is unnecessary. That can prevent operato=
rs =
 to be used at all (too much time would be spend on cloning).
  What if compiler assumes that the 'opXxx' operators always return  =
 temporary objects? Then "a =3D b + c + d;" would be read as:
      a =3D b.opAdd(c).opAddAssign(d);
  That's efficient.
   Now, what if we get rid of the 'opXxx' operators altogether?
  If a class has 'opClone', then the class is treated as a value type:=
=
 statements are compiled with the 'opClone' and 'opXxxAssignment'  =
 operators only. For example, "a =3D b + c + d;" will be read as:
      a =3D b.opClone().opAddAssign(c).opAddAssign(d);
  Then you could always use operators freely and there would be no  =
 redundant operator functions (e.g. 'opAdd' *and* 'opAddAssign'). Of  =
 course, that would also enforce 'a =3D a + b' <-> 'a +=3D b' to be tr=
ue =
 always, but I think so it should be.
  And if there will be a copy/clone operator, lets say '<-', then
      a <- b;
     a <- b + c;
  would be, of course, read as:
      a <- b;     //=3D=3D a =3D b.opClone();
     a =3D b + c;  //=3D=3D a =3D b.opClone().opAddAssign(c);
Take a look at: http://d.puremagic.com/bugzilla/show_bug.cgi?id=3D124
Heh, I should have quessed that this has been proposed before. :) (Well, it didn't include the 'opClone' which could be useful. I actually= = continue this issue under a new post 'Suggestion: wrapping up value type= = objects' as I think it should have its own thread.)
Oct 25 2006