Speedfrage :)



  • 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
    nop

    es 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.


Anmelden zum Antworten