Perfomance
-
kingruedi schrieb:
Bei C++ ist das bei Klassen wichtig, wo der Operator überladen ist, weil da der Compiler nicht mehr optimieren kann, weil er ja nicht weiss, was die Funktion intern macht
außer bei virtuellen funktionen macht der compiler genau das, das ist eine optimierung die schon seit sehr langem im intel compiler ist und im .Net compiler von m$ und die gnu leute sind da sicherlich nicht hinten dran und haben das drinne.
(damit will ich nicht klugscheissen sondern lediglich darauf hinweisen)rapso->greets();
-
sicher das die Compiler das machen? Ich meine der Compiler ahnt ja nicht, was der Prefix oder Postfix Operator macht. Es kann ja sein, dass der Prefix Operator irgend welche anderen Aktionen durchführt (natürlich idr. nicht zu empfehlen, weil es schlecht zu lesen ist :)). Darf der Compiler da einfach reinfummeln?
-
Nö, das darf er ganz sicher nicht. Denn beim Postfix ++ wird ja eine Kopie erzeugt, und mein Programm darf davon abhängen, daß genau diese Kopie auch erzeugt wird, ob sie jetzt gebraucht wird oder nicht...
Deshalb muß er da die Finger rauslassen und daher ist es sinnvoll prefix ++ postifx++ vorzuziehen.
-
also mein compiler optimiert das weg, wenn die kopie nichts macht... der optimiert auch alles unnötige weg, wenn man z.b. ein kreuzprodukt zweier vektoren macht und nur das erste element weiter verwendet, dann berechnet der die restlichen elemente nicht, obwohl das in der vektor-class gekapselt ist, und unabhängig davon wo es benutzt wird, berechnet werden sollte.
ist aber auch länger her, dass ich die beiden ++ sachen verglich und es spricht ja garnichts gegen ++c;
rapso->greets();
-
Welcher Compiler ist das?
Welche Ausgabe erzeugt er bei folgendem Code?#include <iostream> #include <fstream> #include <sstream> #include <iomanip> #include "stdafx.h" class CountCopy { public: static int Copies() { return Copies_; } static void Clear() { Copies_ = 0; } CountCopy() { ++Copies_; } CountCopy(const CountCopy & c) { blub = c.blub; ++Copies_; } const CountCopy & operator++ () { ++blub; return *this; } const CountCopy operator++ (int) { CountCopy tmp(*this); ++*this; return tmp; } private: int blub; static int Copies_; }; int CountCopy::Copies_; int main() { using namespace std; CountCopy c; ++c; cout << "Prefix: " <<CountCopy::Copies() << endl; CountCopy::Clear(); c++; cout << "Postfix: " <<CountCopy::Copies() << endl; cin.get(); }
-
Achja, und auch wenn ich die Konstruktoren auskommentiere und ein CopyCount anlege, einmal mit Prefix und eine Version mit Postfix inkrementiere gibts verschiedene Exe-Files.
-
rapso schrieb:
also mein compiler optimiert das weg, wenn die kopie nichts macht...
dein beispiel wühlt im konstruktor auf statics rum, da kann man nichts wegoptimieren... jeder optimiert sachen weg, wenn man es darf, darauf sind auch compiler gebaut. wenn ein objeckt erstellt wird und nichts macht, dann darf es wegoptimiert werden und das machen manche kompiler. *doppelmoppel*
wenn etwas "wegoptimiert" werden würde, was ein anderes verhalten hervorruft, ist es keine optimierung mehr sondern ein bug... darüber müssen wir uns erst garnicht unterhalten
aber in vielen fällen ist post und pre das gleiche, da muss man sich keinen kopf drüber machen beim optimieren und falls nicht, weil man etwas im konstruktor macht, wass auswirkungen auf das ganze programm hat (siehe dein beispiel), dann wird man ja wohl selbst bei jedem ++ nachdenken welches man verwenden möchte/muss, je nachdem was man bezweckt.
rapso->greets();
-
Jo klar, aber sogar ohne selbstdefinierte Konstruktoren
ist der generierte Code vonclass CopyCount
{
// wie eben, nur ohne eigenen CopyConstr., dafür mit GetBlub
}int main()
{
CopyCount c;
++c;
cout << "Blub: " << c.GetBlub();}
nicht der gleiche, wie wenn ich c++ anstelle von ++c schreibe...
welchen Compiler verwendest Du denn?
-
nein, der code ist sicherlich nicht der gleiche, soll er ja auch nicht, er soll optimiert werden, dabei ist die regel, das optimalste ist das was man nicht machen muss wohl die erste die aufgestellt wurde :).
wenn du sowas wie z.B. for(int a=0;a<pAutoPark->getCount();a++) benutzt und der compiler merkt, dass in der funcktion getCount(); immer der selbe wert zurückgegeben werden wird, wird er den aufruf eventuell wegoptimieren, VC6 hat da noch probleme und deswegen kann man dort Aliasing ein und ausschalten, denn manchmal ändert sich da doch ein kleiner wert aber die schelife bekommt das nicht mit... das zu debuggen sass ich mal fast nen tag... nur ne compiler option.
ich benutze, wie weiter oben erwähnt, den intel und den m$.Net compiler, der intel hat als erstes global optimiert (also in andere cpp geschaut ob sich noch mehr optimieren oder inlinen lässt).
wenn man normalerweise eine leere function in dem header deklariert bzw im cpp definiert, wird sie angesprungen, weil sich kompiler normalerweise nur die header anschauen. der intel hat dagegen auch in die cpp geschaut um constanten wegzuoptimieren oder dinge zu inlinen.das gibt's bei denen bestimmt auch in papern nachzusehen.
rapso->greets();
-
Am meisten Performance holt man IMMER beim Algorithmus heraus. Deshalb bin ich jetzt grad auf der Suche nach einem Profiler für VS.Net *such*
Ihr könnt mir gerne auch ein paar Tipps geben, wo ich suchen mussOder kosten die was?
-
CodeAnalyst von AMD ist 4free.
Sonst schau dir mal VTune von Intel an.
Du könntest aber auch mal die Gnu utilities hernehmen wie gprof usw. Nur ob die mit dem output von VC was anfangen können ist eine andere Frage