Was ist schneller?



  • Simple Frage:
    Was ist schneller?

    int num = vector.size();
    for(int i=0; i < num; i++) {
      // zeugs
    }
    
    oder:
    for(int i=0; i < vector.size(); i++) {
      // zeugs
    }
    

    Oder isses egal?


  • Mod

    Kommt drauf an, z.B. darauf, was in der Schleife passiert. Daher: Probier's doch aus. Zumindest wird die zweite Variante nie schneller sein als die erste, dafür kann die erste natürlich auch gänzlich falsch sein (ich hoffe, der Unterschied ist dir klar).



  • Rein prinzipiell: 1
    Praktisch: vermutlich egal

    Wie wär's mit:

    for (auto i = begin(vector); i != end(vector); ++i)
    {
      ...
    }
    


  • oder noch besser

    size_t vkSize = vector.size();
    for ( size_t i = vkSize - 1; i >= 0; --i )
    

    Vermutlich werden alle diese Minitricks eh schon richtig vom Compiler optimiert.



  • Wird bei 2 in jedem Durchlauf size() aufgerufen?



  • @Travor: Was soll das? Genau das hab ich doch gemacht im 1. Beispiel -.-



  • Das ist relativ einfach per code motion umsetzbar und wenn das ein einigermassen aktueller Compiler nicht umsetzt würde mich das sehr wundern. ^^



  • Travor schrieb:

    oder noch besser

    size_t vkSize = vector.size();
    for ( size_t i = vkSize - 1; i >= 0; --i )
    

    Vermutlich werden alle diese Minitricks eh schon richtig vom Compiler optimiert.

    ist das nicht total cacheunfreundlich?


  • Mod

    PerfFrag schrieb:

    @Travor: Was soll das? Genau das hab ich doch gemacht im 1. Beispiel -.-

    Ein Vergleich gegen 0 kann einen winzigen Taktbruchteil schneller sein als ein Vergleich gegen eine andere Zahl. Aber das kommt dann wirklich ganz stark drauf an was in der Schleife steht, denn rückwärts durch einen vector gehen ist keine so tolle Idee.



  • lolx schrieb:

    ist das nicht total cacheunfreundlich?

    SeppJ schrieb:

    [...] denn rückwärts durch einen vector gehen ist keine so tolle Idee.

    Jap 😉



  • Also kann man ja premature optimization is the root of all evil wieder schreiben.



  • Travor schrieb:

    oder noch besser

    size_t vkSize = vector.size();
    for ( size_t i = vkSize - 1; i >= 0; --i )
    

    Das ist eine Endlosschleife.



  • Es gab da noch einen Bug in meinem Beispiel.

    size_t vkSize = vector.size();
    for ( size_t i = vkSize - 1; i < vkSize ; --i )
    

    Wieso ist es keine gute Idee in einem Vector rückwärts zu laufen?
    Und ja es gibt keinen allzu großen Unterschied:)



  • Travor schrieb:

    Wieso ist es keine gute Idee in einem Vector rückwärts zu laufen?

    Cache und so...



  • achso.. Stimmt wohl.. danke



  • Travor schrieb:

    size_t vkSize = vector.size();
    for ( size_t i = vkSize - 1; i < vkSize ; --i )
    

    Es wurden schon Leute für weniger verprügelt.



  • Vor allem ist <=, >=, >, < im Regelfall langsamer als ==/!=.
    Dh. wenn es nicht logisch relevant ist, am Besten != nehmen.



  • dot schrieb:

    Travor schrieb:

    Wieso ist es keine gute Idee in einem Vector rückwärts zu laufen?

    Cache und so...

    Cache und so... was?
    Dem Cache ist es egal, und die Prefetch-Logik der CPU schnallt es auch.

    Also ich sehe da jetzt kein echtes Problem.



  • hustbaer schrieb:

    dot schrieb:

    Travor schrieb:

    Wieso ist es keine gute Idee in einem Vector rückwärts zu laufen?

    Cache und so...

    Cache und so... was?
    Dem Cache ist es egal, und die Prefetch-Logik der CPU schnallt es auch.

    Sie laden je nachdem in welche Richtung man den Speicher benutzt in eine andere Richtung Blöcke vor?
    Wäre mir jetzt neu, aber bestimmt im Bereich des möglichen.



  • Michael E. schrieb:

    Travor schrieb:

    size_t vkSize = vector.size();
    for ( size_t i = vkSize - 1; i < vkSize ; --i )
    

    Es wurden schon Leute für weniger verprügelt.

    😃



  • drakon schrieb:

    hustbaer schrieb:

    dot schrieb:

    Travor schrieb:

    Wieso ist es keine gute Idee in einem Vector rückwärts zu laufen?

    Cache und so...

    Cache und so... was?
    Dem Cache ist es egal, und die Prefetch-Logik der CPU schnallt es auch.

    Sie laden je nachdem in welche Richtung man den Speicher benutzt in eine andere Richtung Blöcke vor?
    Wäre mir jetzt neu, aber bestimmt im Bereich des möglichen.

    Zumindest die "dicken" CPUs sollten das können.
    http://www.intel.com/Assets/en_US/PDF/manual/248966.pdf

    7.1 GENERAL PREFETCH CODING GUIDELINES schrieb:

    * Take advantage of the hardware prefetcher’s ability to prefetch data that are accessed in linear patterns, in either a forward or backward direction.

    Ich hatte auch mal ein Dokument gefunden wo noch etwas genauer beschrieben war was die CPU um die es ging alles kann - kann den Link aber nimmer finden.

    Andrerseits können es vielleicht weniger "dicke" CPUs wie ARM etc. nicht.

    Von daher ändere ich mal meine Meinung :): wenn's leicht geht bitte immer vorwärts. Bei Programmen für Desktop Plattformen würde aber auch keinen besonderen Aufwand betreiben "rückwärts" zu vermeiden - wenn's rückwärts einfacher geht, dann eben rückwärts.


Anmelden zum Antworten