Anfängerfrage zur Preformance
-
Ich hab erst vor ein paar Wochen mit C angefangen und hoffe einfach mal dass die Frage nicht allzu lächerlich ist
Also, ich wollte wissen wie man normalerweise die Geschwindigkeit von Programmteilen vergleicht. Ich hab es jetzt so gemacht, dass ich die Prozessorzeit vor dem Programmabschnitt nehme, dann die Zeit nach dem Abschnitt und die Differenz ist dann etwa die Zeit in ms die zum Ausführen dieses Programmteils benötigt wurde. Macht man das normalerweise anderst? Die Frage kommt halt auf wenn ich zwei Lösungen für ein Problem habe, dann würd ich so testen welche schneller ist. Die nächste Frage betrifft Kontrollstrukturen. Ich wollte testen wann zum Beispiel eine for-Schleife und wann eine while-Schleife schneller ist. Bei dem Test war dann die for-Schleife beim reinen zählen um etwa 10% schneller, und wenn noch andere Rechenoperationen dabei sind war die while-schleife um 60% schneller. Bedeutet das jetzt dass ich für alles (ausser das reine zählen) while-Schleifen verwenden sollte?
-
Achso eins hab ich noch vergessen:
Ich wollte testen wie genau die Zeitmessung überhaupt ist, und dabei kam raus, dass die Abweichung etwa 7 bis 8 ms beträgt. Ist das dann das minimale Zeitfenster des Betriebssystems von dem ich schon gelesen hab? (~10ms bei Windows).
-
Du hast ja mitbekommen, dass Windows Zeitfenster hat, in denen das Programm ausgeführt hast. Das führt dazu, dass du "kurze" Strukturen nicht hinreichend genau messen kannst. (Ne for-schleife, die bis 100 zählt nimmt auf heutigen Rechner - fast - gar keine Zeit in Anspruch)
Deswegen musst du Codeteile, die du messen möchtest mehrfach ausführen und die Zeit über die gesamte Ausführung messen.
Wie das mit dem Zeitverhalten zwischen for- und while-Schleife aussieht, weiß ich nicht. Aber deine gemessenen 60% Unterschied zweifle ich sehr stark an.
Was auch ganz wichtig ist: Wenn du - zum Beispiel mit dem VC++ - im Debug-Modus misst und dann mal mit dem Release-Modus, wirst du auch Zeitunterschiede feststellen.
-
Du kannst Dir auch eine Messstation basteln mit dem Performance Counter, zB so ähnlich wie in diesem Thread: http://www.c-plusplus.net/forum/viewtopic-var-t-is-157925-and-highlight-is-%2Aperformancecounter%2A.html
Die Genauigkeit ist rund um 10ms. Windows ist kein Echtzeit-OS.
Hab mal mit 10000mal Sleep(10) getestet, gibt etwas zwischen 10.3 und 10.8 ms.
Solltest auch drauf achten, dass ncht zuviel andere Prozesse laufen, um die Ergebnisse einigermassen genau vergleichen zu könnenAus while und for generiert der Compiler mit Optimierung an (/O2 oder /Ox) wohl ähnlichen Code. Wenn du im Debug misst, gibts schon unterschiede, aber im release mode sollten die minim sein.
Ansonsten gibts noch Profiler, wie CodeAnalyst von AMD. (Ist gratis, man muss sich aber registrieren per eMail).
Die zeigen Dir dann auf, wo wieviel Zeit verbraucht wird.
-
Bei den Tests hab ich natürlich schon entsprechen viele Wiederholungen gemacht.
Einmal lasse ich die For- und die While-Schleife einfach bis 50 mio zählen.
Dazu braucht die For-Schleife ~180 ms und die While-Schleife ~200 ms.Dann lasse ich die For-und die While-Schleife 100 mio mal den Zähler quadrieren und an eine Variable übergeben.
Dazu braucht dann die For-Schleife 406ms und die While-Schleife 236ms (also doch nicht 60%, aber trotzdem ein ziemlich großer Unterschied.
-
Zeig mal den Quellcode dazu
-
Hau mal die Optimierung rein und teste im Release Mode.
Edit:
Ich hab auch schon festgestellt, dass for Schleifen ziemlich langsam sind im Debug Modus. Ist aber praktisch null im Release mit /Ox (VC++2k5).
-
...oder den vom compiler erzeugten asm-code nehmen und unter 'nem simulator ausführen, der die verbrauchten taktzyklen zählt. z.b. sowas: http://www.simplescalar.com/
-
Ah sorry für die Verwirrung, ich hatte einen Fehler im Code

Die For-Schleife ist etwas schneller beim zählen (~10%).
Die While-Schleife ist etwas schneller bei sonstigen berechnungen (nur ein paar Prozent).
-
Code sieht so aus:
#include <time.h> #include <iostream> #include <math.h> using namespace std; void sleep(unsigned int mseconds) { clock_t goal = mseconds + clock(); while (goal > clock()); } int main(int argc, char *argv[]) { clock_t start, stop; int z = 0, i = 0; double l, k; sleep(1000); start = clock(); for( z = 1; z <= 50000000; z += 1); stop = clock(); cout << "Dauer der For-Schleife (Zaehlen): " << (stop - start) << endl; start = clock(); while(i <= 50000000) { i += 1; } stop = clock(); cout << "Dauer der While-Schleife (Zaehlen): " << (stop - start) << endl; i = 0; start = clock(); for( z = 1; z <= 100000000; z += 1) { k = (z*z); } stop = clock(); cout << "Dauer der For-Schleife (Quadrieren): " << (stop - start) << endl; start = clock(); while(i <= 100000000) { i += 1; l = (i*i); } stop = clock(); cout << "Dauer der While-Schleife (Quadrieren): " << (stop - start) << endl; i = 0; start = clock(); for( z = 1; z <= 10000000; z += 1) { k = pow(z, 0.5); } stop = clock(); cout << "Dauer der For-Schleife (Math-Fkt): " << (stop - start) << endl; start = clock(); while(i <= 10000000) { i += 1; l = pow(i, 0.5); } stop = clock(); cout << "Dauer der While-Schleife (Math-Fkt): " << (stop - start) << endl; sleep(5000); }