Optimierung mal wieder



  • Hi,

    kann man das

    CVector3D& CVector3D::operator*= (const CVector3D &other)	
    { 
    	(*this) = (*this) * other;
    
    	return (*this);
    }
    

    durch das:

    CVector3D& CVector3D::operator*= (const CVector3D &other)	
    { 
    	return ((*this) = (*this) * other);
    }
    

    ohne bedenken ersetzen?



  • Das ist keine Optimierung, du kannst aber:

    (*this) *= other;
    

    schreiben anstatt (*this) = (*this) * other;



  • @Mis2com
    Er versucht doch aber gerade den *= operator zu implementieren.



  • CVector3D& CVector3D::operator*= (const CVector3D &other)   
    {
        return *this = *this * other;
    }
    

    Die Klammern sind unnötig.

    Mis2com schrieb:

    Das ist keine Optimierung, du kannst aber:

    (*this) *= other;
    

    schreiben anstatt (*this) = (*this) * other;

    dann ruft operator*= sich selbst unendlich auf == Rekursion.



  • @Mis2com:
    Du bist echt ein kewler, noob, weiste das? Überall wo du bist, ist nur Unsinn.

    @godlikebot && Shlo
    THX



  • nein nein nein. falsch rum.

    nicht der op*= wird durch op* implementiert sondern der op* wird durch den op*= implementiert. sonst ist es viel zu lahm.

    Foo operator*(Foo const& a, Foo const& b)
    {
      Foo result(a);
      result*=b;
      return result;
    }
    

    so ist es schön.



  • optimierung schrieb:

    @Mis2com:
    Du bist echt ein kewler, noob, weiste das? Überall wo du bist, ist nur Unsinn.

    und du willste hilfe haben? verdammter troll kriech in dein loch zurück



  • Shade Of Mine schrieb:

    nein nein nein. falsch rum.

    nicht der op*= wird durch op* implementiert sondern der op* wird durch den op*= implementiert. sonst ist es viel zu lahm.

    Foo operator*(Foo const& a, Foo const& b)
    {
      Foo result(a);
      result*=b;
      return result;
    }
    

    so ist es schön.

    Sorry, aber dürfte das nicht ohne Belang sein? Ich denke nicht, dass der Compiler lahmeren Code generiert, wenn man es andersrum macht. Nach dem was ich mitbekommen habe, wird eher der *= durch den * implementiert, in C# muss das sogar so sein.



  • Optimizer schrieb:

    Sorry, aber dürfte das nicht ohne Belang sein? Ich denke nicht, dass der Compiler lahmeren Code generiert, wenn man es andersrum macht.

    Oh doch.

    a=ab;
    ist lahmer als
    a
    =b;

    sofern wir davon ausgehen, dass wir einen 0815 Compiler haben. Natürlich _kann_ er es optimieren, tut aber keiner den ich kenne. (Achtung: wir reden von Klassen, bei builtins können sie das natürlich schon).

    wenn wir den op = (den schnellen) durch den op (den langsamen) implementieren, wirds lahm.

    vergleichen wir mal:

    Foo operator*(Foo const& a, Foo const& b)
    {
      return Foo(a.value() * b.value()); //1 kopie, RVO killt die 2. kopie
    }
    
    Foo& Foo::operator*=(Foo const& a)
    {
      return (*this) =  1 kopie
        (*this) * a; //1 kopie
    }
    
    //und:
    
    Foo operator*(Foo const& a, Foo const& b)
    {
      Foo result(a); //1 kopie
      result*=b;
      return result; //NRVO - fällt also weg
    }
    
    Foo& operator*=(Foo const& a)
    {
      value() *= a.value();
      return *this;
    } //0 kopien
    

    Was ist besser?

    Natürlich ist keins wirklich teuer - aber meine variante ist nicht nur die schnellere, sondern auch die gängigere (und die schönere - schließlich ist ein *this=foo; doch nicht schön, oder?)

    Nach dem was ich mitbekommen habe, wird eher der *= durch den * implementiert, in C# muss das sogar so sein.

    In C++ sicher nicht.
    In C# kann man den op*= nicht überladen. man überlädt den op* und daraus erstellt der compiler code für den op*= - inwiefern der code da schnell sein kann, weiss ich allerdings nicht.



  • *alten Thread wieder entdeck*

    Warum das in C# performant geht, ist natürlich schon klar.
    In C# schreibst du halt dein '*':

    public static Rational operator*(Rational a, Rational b)
    	{
    		return new Rational(a.num * b.num, a.denom * b.denom);
    	}
    

    Und daraus generiert der Compiler wahrscheinlich sowas wie:

    a *= b
    ->
    a = a * b

    Was ja nicht mehr kostet als der operator* weil eh nur die Referenz zugewiesen wird, wohingegen in C++ der Bruch kopiert würde. Der vorherige Bruch a wird gar nicht verändert, es wird einfach nur an die Referenz das Ergebnis der Multiplikation zugewiesen.

    Das mit dem op* über op*= implementieren in C++ klingt allerdings logisch. Werd ich mir merken. 🙂


Anmelden zum Antworten