Speedfrage :)
-
Also ich weiss ja nicht ob das hilfreich ist, aber:
#include <stdio.h> #include <windows.h> int main(void) { DWORD st; long c; long d=0; int versuche=10; for(int x=0; x<versuche; x++){ c=100000000; st = GetTickCount(); while(c){ c--; } printf("%d ms\n", GetTickCount()-st); d+=GetTickCount()-st; } printf("---------\n%d ms", d/versuche); printf("\n\n"); d=0; for(int x=0; x<versuche; x++){ c=10000000; st = GetTickCount(); los: c--; if(c>0) goto los; printf("%d ms\n", GetTickCount()-st); d+=GetTickCount()-st; } printf("---------\n%d ms", d/versuche); getchar(); return 0; }
Gibt bei mir folgende Ausgabe:
410 ms 411 ms 400 ms 401 ms 390 ms 411 ms 391 ms 420 ms 401 ms 390 ms --------- 402 ms 90 ms 81 ms 60 ms 50 ms 50 ms 60 ms 50 ms 50 ms 50 ms 50 ms --------- 59 ms
womit doch eigentlich gezeigt wäre, dass goto schneller ist.
bin mir da aber nicht sicher, ob das allzuviel mit dem Thema zutun hat...cu para
-
Man kann das noch etwas optimieren, um den Unterschied *noch* deutlicher herauszustellen:
Original erstellt von paranoiac.org:
**```cpp
#include <stdio.h>
#include <windows.h>int main(void)
{
DWORD st;
long c;
long d=0;
int versuche=10;for(int x=0; x<versuche; x++){ c=100000000; st = GetTickCount(); while(c){ c--; } printf("%d ms\n", GetTickCount()-st); d+=GetTickCount()-st; } printf("---------\n%d ms", d/versuche); printf("\n\n"); d=0; for(int x=0; x<versuche; x++){ c=100; st = GetTickCount(); los: c--; if(c>0) goto los; printf("%d ms\n", GetTickCount()-st); d+=GetTickCount()-st; } printf("---------\n%d ms", d/versuche); getchar(); return 0;
}
Jetzt ist goto *noch* schneller. Cool oder?
-
Habs au gemerkt...
[ Dieser Beitrag wurde am 21.11.2002 um 15:16 Uhr von paranoiac.org editiert. ]
-
Das hängt einfach vom Compiler ab.
Allerdings gibt es einen bedeutenden Unterschied zwischen:while (1) ; //und x: goto x;
denn ';' ist ein "Befehl" Es sind also Programme gültig wie z.B.:
int main () {; ; ; ; ; ; ; return 0; }
Normalerweise würde er dann die ';' in NOPs übersetzen, es kann aber auch sein, dass der Compiler die weckoptimiert. Da ja logisch kein Unterschied zwischen den beiden Konstrukten besteht.
Also mein Compiler (BCC4.5.2) übersetzt die Anweisungen gleich. Hier der entscheidene Auszug:; ; main () ; ; ; { ; while (1) ; ?debug L 3 @1: @2: jmp short @2 ; ; ; ; ; x: ; goto x; ; ?debug L 7 @3: jmp short @3 ; ; } ; ?debug L 8 @4: ret
[ Dieser Beitrag wurde am 21.11.2002 um 15:48 Uhr von -bg- editiert. ]
-
Original erstellt von paranoiac.org:
**Also ich weiss ja nicht ob das hilfreich ist, aber:while(c){ c--; } los: c--; if(c>0) goto los;
womit doch eigentlich gezeigt wäre, dass goto schneller ist.
bin mir da aber nicht sicher, ob das allzuviel mit dem Thema zutun hat...cu para
:D**Allerdings ist das nicht fair weil ...
beim goto hast Du c>0
und beim while c ( sprich c != 0 )
das müsste ohne Compiler-Optimierung verschiedenen assambler geben
ausserdem ist der Goto eine Fuss-schleife und die while-schleife eine Kopfschleife.Gruß
-
Könnt ihr das mal lassen? Er hat einmal 10 Millionen und einmal 100 Millionen Durchläufe, ich dachte eigentlich mein Posting stellt das heraus, aber ich muß wohl noch deutlicher werden.
-
ob du mit == != >= <= < > prüfst macht keinen Unterschied, wenn der Compiler NICHT optimiert, dann ergibt das jeweils ein cmp gefolgt von
je, jne, jnb, jna, ja oder jb.
Wenn er allerdings optimiert, kann er bei Prüfungen wie:
x != 0
das mit einem test x übersetzen, der glaube ich manchmal schneller ist.
Aber wie gesagt es lag eh ein Fehler im Testprog vor. Aber ich möchte dazu noch sagen, dass es Ratsam ist zwei verschiedene Programme zu schreiben, da sonst evntl. Caching oder div. Packagelimits, das Ergebnis verfälschen können.mfg
-bg-
-
@-bg-
ich würde gerne wissen wo steht das ";" ein befehl ist. wenn da so wäre dann müsste man doch nicht "printf("A");" schreiben sondern könnte einfach "printf("A")" schreiben. sonst würde man ja immer schreiben "printf("A")NOP" was keinen sinn macht.
meines wissens teilt ";" dem compiler einfach nur mit das ein befehl hier abgeschlossen wird, damit man auch mehere befehle in eine reihe schreiben kann, wie z.b.: "printf("A");printf("B");printf("C");"
also von einem befehl zu sprechen ist glaube ich falsch. ";" versursacht höchstens, das der compiler "NOP" erstellt, weil kein befehl davor steht bzw, weil KEIN befehl abgeschlossen wird. eben NoOperation vor dem ";"
-
bei printf("a"); ist das ; Teil des Befehls. Bei ; ist ; der Befehl selbst. Nicht jedes ; ist ein eigener Befehl. Sehr deutlich zu sehen bei printf(";;");
-
Jep, da muss man tatsächlich unterscheiden.
if Bedingung erfüllt ; else anderes
heisst in diesem Falle z.B.: if Bedingung erfüllt, dann leere Anweisung, also mache nichts.
Zumindest habe ich das so gelernt
Kernighan / Ritchie haben das auch so rausgestellt. Ich glaube, ; an sich ist im Ansi-Standard sogar explizit als Befehl aufgeführt.[ Dieser Beitrag wurde am 22.11.2002 um 15:49 Uhr von Casi666 editiert. ]
-
okok
ich interpretier es einfach anders, es ist aber in etwa das selbe!
für mich schließt bei
if (true)
printf("A");
else
printf("B");das ";" den befehl printf("A") ab
und bei
if (true)
;
else
printf("B");schließt das ";" eine leere anwesiung ab.
denn man kann ja genauso wenig
if (true)
printf("A) //ohne ";"
else
printf("B");schreiben
und genauso wenig
if (true)
//ohne ";"
else
printf("B");für mich ist ";" nur ein bestandteil eines befehls aber kein befehl selber. wenn das so wäre dann müsste das ";" beim compilieren in irgendwelche maschinenbefehle übersetzt werden. das tut der compiler aber nicht, egal bei welchem befehl.
ein 'MyFunc();' wird zu
call MyFunc
und nicht zu
call MyFunc
nopes ist eben nur eine anweisung für den compiler, die befehle abschliesst, aber kein befehl selber, kann aber auch sein das ich "befehl" falsch interpretiere.
ich hoffe ihr versteht diesen kleinen unterschied
-
Die Diskussion ist reichlich sinnlos. Man kann sich im Rahmen des Standards nicht darüber unterhalten, welcher Code wann generiert werden könnte ... es ist alles erlaubt, was die as-if-Regel nicht verletzt. Geht man also vom Stnadard weg, kann man nur noch darüber diskutieren, was existierende oder naheliegende Implementierungen machen. Gibt es eine, die für leere Anweisungen NOPs generiert? Sinnvoll oder gar naheliegend ist das mit Sicherheit nicht.