Was ist effizienter



  • Hallo zusammen,

    ich habe hier zwei Codeschnipsel und frage mich, was schneller ist. Ersterer ist sicherlich schöner, aber falls der Compiler nicht schlau ist, sicherlich langsamer. Zweiterer ist redundant, aber auch ein dummer Compiler kriegt schnellen Code hin.

    //1
    for(int i=0; i<very_big_number; i++) {
      if(a) {
        komplizierte_funktion();
      }
      else {
        kompliziertere_funktion();
      }
    }
    
    //2
    if(a) {
    for(int i=0; i<very_big_number; i++) {
     komplizierte_funktion();
    }
    }
    else {
    for(int i=0; i<very_big_number; i++) {
     kompliziertere_funktion();
    }
    }
    

    Beim erten Codeschnipsel kämen pro Schleife ein Vergleich dazu...



  • Der Compiler ist ziemlich sicher schlau genug, wenn du mit Optimierungen (GCC: -O3) kompilierst.
    http://en.wikipedia.org/wiki/Loop_unswitching



  • hominilupus schrieb:

    Der Compiler ist ziemlich sicher schlau genug, wenn du mit Optimierungen (GCC: -O3) kompilierst.
    http://en.wikipedia.org/wiki/Loop_unswitching

    Ist dein Ziel nicht, Redundanz zu meiden?



  • Die Frage kam erst kürzlich auf, aber ich finde den Thread auf die Schnelle nicht...



  • out schrieb:

    hominilupus schrieb:

    Der Compiler ist ziemlich sicher schlau genug, wenn du mit Optimierungen (GCC: -O3) kompilierst.
    http://en.wikipedia.org/wiki/Loop_unswitching

    Ist dein Ziel nicht, Redundanz zu meiden?

    Generell schon. Deshalb ist -O2 auch manchmal schneller als -O3, weil -O3 eben viel Redundanzen reinbringt. Unswitchen bringt halt lokal einen Vorteil (ab etwa 10000 Loopdurchläufen), aber global einen Nachteil. Und wenn dann noch Loop-Unrolling dazukommt, hat man ein Riesenbinary...



  • hominilupus schrieb:

    out schrieb:

    hominilupus schrieb:

    Der Compiler ist ziemlich sicher schlau genug, wenn du mit Optimierungen (GCC: -O3) kompilierst.
    http://en.wikipedia.org/wiki/Loop_unswitching

    Ist dein Ziel nicht, Redundanz zu meiden?

    Generell schon. Deshalb ist -O2 auch manchmal schneller als -O3, weil -O3 eben viel Redundanzen reinbringt. Unswitchen bringt halt lokal einen Vorteil (ab etwa 10000 Loopdurchläufen), aber global einen Nachteil. Und wenn dann noch Loop-Unrolling dazukommt, hat man ein Riesenbinary...

    Huch sorry, aus Versehen den falschen zitiert. Die Frage sollte eigentlich an freakC++ gehen. 🤡



  • Weil wir heutzutage ja auch so wenig Speicher haben, dass die paar Bytes eine Rolle spielen.



  • Kellerautomat schrieb:

    Weil wir heutzutage ja auch so wenig Speicher haben, dass die paar Bytes eine Rolle spielen.

    Weil wir ja heute auch so langsame CPUs haben, dass die paar Takte eine Rolle spielen.



  • Nexus schrieb:

    Kellerautomat schrieb:

    Weil wir heutzutage ja auch so wenig Speicher haben, dass die paar Bytes eine Rolle spielen.

    Weil wir ja heute auch so langsame CPUs haben, dass die paar Takte eine Rolle spielen.

    Kann es, je nach Anwendung.



  • Kellerautomat schrieb:

    Kann es, je nach Anwendung.

    Genau. Und zwar in beiden Fällen 🙂

    Mir ist schon klar, was du sagen willst. Geschwindigkeit ist auch oft wichtiger als Speicher. Aber das ist kein Grund, gute Hinweise auf Speicherfresser kategorisch als veraltet abzutun; ansonsten könnte man schliesslich immer mit -O3 arbeiten.

    Bedenke auch: Mehr Code bedeutet weniger Platz im Instruction-Cache. Wenn man Pech hat, muss öfter nachgeladen werden, und verliert wieder Geschwindigkeit. Übrigens das gleiche Prinzip bei Inline-Funktionen. Durch falsches Optimieren erreicht man das Gegenteil.


Anmelden zum Antworten