for-Optimierung



  • Wurstinator schrieb:

    Der Compiler ist also schlau genug, zu erkennen, ob sich während der Schleife etwas am Funktionswert ändert und optimiert gegebenenfalls.
    Ok, danke 🙂

    Bei Funktionen in einer anderen Übersetzungeinheit nicht. Der GCC könnte es wahrscheinlich, wenn du die aufzurufende Funktion als "pur" deklarierst, aber das ist dann nicht mehr portabel. Eine andere Möglichkeit wäre Link-Time-Optimization.



  • Die ~i Variante war bloss als Beispiel für eine komplett bescheuerte Schreibweise gedacht. Wenn es wichtig ist sagt es, vielleicht fällt mit ja noch was bekloppteres ein.

    Und ja, da muss dann natürlich foo() - 1 hin.



  • Mechanics schrieb:

    Nein, siehe Antwort von knivil. Ich bin sogar ziemlich skeptisch, ob er das bei so vielen Funktionen tatsächlich erkennen kann.

    Und ich bin mir ziemlich sicher, dass VS, GCC und der Intel Compiler das bei allen Funktionen packen die geinlined werden.

    Mechanics schrieb:

    obskuren Tricks

    Hättest du die letzten 4 Seiten gelesen, sollte dir klar sein, dass ich das eben nicht als obskuren Trick ansehe. std::tuple, std::function und std::make_shared sind obskure Tricks, aber doch nicht "i-- != 0". 😉



  • Liebes Keks,
    DU empfindest es vielleicht nicht als obskure Tricks.
    Andere schon.
    Ist eben alles Ansichtssache.

    Und bei Kritik im Sinne von "das versteht ja keiner" einfach immer sagen "pf, ich versteh das super" ist irgendwie nicht sinnvoll.



  • cooky451 schrieb:

    Mechanics schrieb:

    Nein, siehe Antwort von knivil. Ich bin sogar ziemlich skeptisch, ob er das bei so vielen Funktionen tatsächlich erkennen kann.

    Und ich bin mir ziemlich sicher, dass VS, GCC und der Intel Compiler das bei allen Funktionen packen die geinlined werden.

    Mhm, ja, täusch dich mal nicht.



  • knivil schrieb:

    krümelkacker schrieb:

    for (size_t i = foo(); ~i; i--)
        ...
    

    Sie läuft von einschließlich foo() bis ausschließlich 0.

    Bei mir lauft sie sogar bis einschliesslich 0.

    Jo, stimmt. Da habe ich mich echt vertan. Ich finde ~i irgendwie weniger lesbar als das i-->0 in anderen Schleifen.

    knivil schrieb:

    Wie würdest du denn eine Schleife bauen, die
    von ausschließlich foo() bis einschließlich 0
    läuft?

    for (size_t i = foo()-1; ~i; i--)
    

    So?

    Ist das dein Ernst? Tja, so kann's gehen. for(;;) ist wohl doch zu mächtig und wenig lesbar, wenn ich mir diese Tricks i-->0 bzw ~i zum Umgehen des Unterlaufproblems anschaue ...

    Kann mir vorstellen, dass for-range bald so oder so ähnlich genutzt wird:

    for (auto i : reversed(range(0,foo()))) {
    
    }
    

    oder in Boost.Range Pipe-Syntax:

    for (auto i : range(0,foo()) | reverse) {
    
    }
    

    🙂



  • Das schreit nach einer Spracherweiterung...

    for (auto i ~: dings)
    

    😃



  • cooky451 schrieb:

    Hättest du die letzten 4 Seiten gelesen, sollte dir klar sein, dass ich das eben nicht als obskuren Trick ansehe.

    Ich hab alles gelesen und ich weiß, dass du das nicht als obskuren Trick ansiehst. So obskur find ich das jetzt auch nicht mal, die Aussage war nicht ausschließlich darauf bezogen. Aber es ist eben obskur genug. Ich kann mich nur wiederholen, je einfacher und dümmer der Code ist, desto besser ist es meist. Alles was nicht absolut straight forward ist, ist nur eine zusätzliche Stör- und Fehlerquelle.



  • hustbaer schrieb:

    Das schreit nach einer Spracherweiterung...

    for (auto i ~: dings)
    

    😃

    Könnt' man nicht einfach ein neues "reversed_for" einführen? Das wäre doch schöner als das, wo man sich ohne Vorkenntnisse einfach fragt, was die Tilde da jetzt soll...



  • Ich wollte es wissen:

    noinline unsigned test_klassisch(unsigned n)
    {
      unsigned counter = 0;
      unsigned bla = foo();
      for( unsigned i = 0; i < bla; ++i )
           counter += i * n;
      return counter;
    }
    
    noinline unsigned test_dekrementierend(unsigned n)
    {
      unsigned counter = 0;
      for( unsigned i = foo(); i-- != 0; )
           counter += i * n;
      return counter;
    }
    
    noinline unsigned test_range(unsigned n)
    {
      unsigned counter = 0;
      for ( auto i : irange(0u,foo()) | reversed) 
            counter += i * n;
      return counter;
    }
    

    Ergebnis: http://81.169.152.91/etc/results.html



  • Athar schrieb:

    Ich wollte es wissen:

    Und hast dabei die Schleife falsch abgeschrieben..

    Athar schrieb:

    Ergebnis: http://81.169.152.91/etc/results.html

    Hatten wir genau den gleichen Benchmark nicht schon vor ein paar Seiten? Oo Ja genau, und hatten festgestellt dass GCC die Optimierung hier einfach nicht rafft, im Gegensatz zu VS. Interessant wäre höchstens noch ein Vergleich auf einem i386 mit VS.



  • jeder sagt es ist unleserlicher, aber cooky451 findet es leserlich, also hat cooky451 recht. 🙄

    cooky451 hast du schon mal einen profiler verwendet und hast dann festgestellt, dass die klassischen Schleifen dein Programm langsam machen und nicht der Schleifeninhalt?


Anmelden zum Antworten