Performance verschiedener "Schleifen"-Typen
-
Hallo!
ich habe gerade ein kleines Programm geschrieben, um verschiedene (Endlos-)Schleifen auf ihre Performance zu untersuchen:
#include <iostream> #include <windows.h> using namespace std; unsigned int b=2000000000; unsigned int a=0; int func() //Funktion für den rekursiven Ansatz { ++a; if(a==b) return 1; return func(); } int main() { DWORD tick = GetTickCount(); a=0; for(;;) //Ansatz mit for-schleife { ++a; if(a==b) break; } cout<<GetTickCount()-tick<<endl; //----------------------------------- a=0; tick = GetTickCount(); punkt1: //Ansatz mit goto ++a; if(a==b) goto punkt2; goto punkt1; punkt2: cout<<GetTickCount()-tick<<endl; //----------------------------------- a=0; tick = GetTickCount(); while(true) //Ansatz mit While Schleife { ++a; if(a==b) break; } cout<<GetTickCount()-tick<<endl; //----------------------------------- a=0; tick = GetTickCount(); func(); //Rekursiver Ansatz cout<<GetTickCount()-tick<<endl; return 0; }
Dabei kommt (wenig überraschend) heraus, dass die ersten drei Varianten ungefähr gleich schnell sind (wobei die for( ; ; ) Variante ja theoretisch die schnellste sein sollte (oder?))
Was mich aber wirklich überrascht hat, ist, dass die rekursive Variante mehr als doppelt so schnell ist, wie die anderen Varianten. Ich dachte immer dadurch, dass die Funktion immer wieder aufgerufen werden muss, leidet die Performance.
Wie ist es zu erklären, dass die rekursive Variante doppelt so schnell ist wie die Anderen???
-
Ich glaube das ist das sinnfreiste was ich heute gelesen habe.
-
Die "Geschwindigkeit" der einzelnen Konstrukte hängt stark vom Code und der Optimierung deines Compilers ab. Triviale Berechnungen in Schleifen und rekursiven Funktionen können im günstigsten Fall ganz weg optimiert werden.
Gerade deine Rekursive Funktion ist so ein Kandidat, das Funktionsergebnis steht ja bereits vor dem Eintritt in die Funktion fest, es wird immer 1 sein. Ein guter Compiler bemerkt dies und wird die Funktion an dieser Stelle gar nicht erst ausführen, sondern "quasi" direkt die 1 zurück geben.
-
Geschwindigkeitsmessungen von (Endlos-) Schleifenkonstrukten ist genauso wie Optimierung des Idleloops.
-
prinzipiell würde jede schleife gleich schnell funktionieren, da die doch nach dem compillieren (assembler technisch) immer in ein goto und einen vergleich zerlegt werden, der die variable die hochzählt prüft, wenn einer definiert wurde. optimierungen sind von der schleifenart denke ich auch unabhängig.