2017-05-04 5 views
1

Ich machte eine LeetCode-Herausforderung (here) zum Spaß und war überrascht, dass die while-Schleife effizienter als die for-Schleife war. Ich hätte erwartet, dass der Compiler identischen Code generiert (auch nach diesen question and answers), aber die Laufzeiten sind unterschiedlich.While-Schleife ist effizienter als für Schleife. Was könnte der Grund sein?

Die while-Schleife betrug etwa 3 ms, während die for-Schleife etwa 6 ms benötigte. Ich habe es ein paar Mal wiederholt und es scheint oft so zu sein.

Ich habe leider nicht die Testfälle, und ich habe keine Informationen über Compiler verwendet, die Architektur oder Optimierungen festgelegt. Ich denke, es ist nicht wichtig, weil die Programme fast identisch sind und den gleichen Compiler, die gleiche Architektur und die gleichen Optionen verwenden.

Irgendwelche Ideen oder Erfahrungen in dieser Angelegenheit?

For-Schleife:

vector<int> twoSum(vector<int>& numbers, int target) { 
    int upper = numbers.size() - 1; 
    int lower = 0; 
    int sum; 

    for (;lower<upper;) { 
     sum = numbers[lower] + numbers[upper]; 
     if (sum == target) { 
      return vector<int> { lower+1, upper+1 }; 
     } else if (sum > target) { 
      upper--; 
     } else { 
      lower++; 
     } 
    } 
} 

While-Schleife:

vector<int> twoSum(vector<int>& numbers, int target) { 
    int upper = numbers.size() - 1; 
    int lower = 0; 
    int sum; 

    while (lower<upper) { 
     sum = numbers[lower] + numbers[upper]; 
     if (sum == target) { 
      return vector<int> { lower+1, upper+1 }; 
     } else if (sum > target) { 
      upper--; 
     } else { 
      lower++; 
     } 
    } 
} 
+1

Erstellen Sie ein [mcve]. – user2079303

+3

Seltsam; Ich kann mir keinen Grund dafür vorstellen, es sei denn, die Codegenerierung ist wirklich schlecht und die Optimierungen sind deaktiviert. –

+1

Wie oft haben Sie die Schleifen ausgeführt? Gab es Optimierungen? Micro-Benchmarking kann sehr schwierig sein. – NathanOliver

Antwort

0

Alle Loops folgen dem gleichen Muster:

{ 
// Initialize 
LOOP: 
if(!(/* Condition */)) { 
    goto END 
} 

// Loop body 

// Loop increment/decrement 
goto LOOP 
} 
END: 

Ihr Test muss durch die verfügbare Rechenleistung unterschieden haben Ihre ZENTRALPROZESSOR.

+0

Ich würde die Negation in dem Zustand vermeiden, es scheint unnötig. – Jonas

+0

Wenn die Negation nicht da wäre, dann wäre Ihre C++ codierte Bedingung entgegengesetzt zu dem, was sie sein soll. Dies ist unter der Haube von C++ –

+0

Das ist nicht was ich meinte. Ich würde die if-Anweisung ändern, um nur die Bedingung zu überprüfen und dann den if-Body den Schleifenkörper, den Inkrement-Schritt und die Gehe-zu-Schleife enthalten zu lassen. – Jonas

4

Sie haben nicht genug oder lange genug Tests ausgeführt, Benchmarks in Millisekunden sind schwer zu überprüfen.

Ein besserer Weg ist die generierte Baugruppe zu vergleichen: for-loop und while-loop. Die Snippets werden mit maximaler Optimierung (-O3) mit g ++ 6.3 kompiliert. Daraus wird deutlich, dass es überhaupt keinen Leistungsunterschied gibt, da die Montage für die beiden exakt gleich ist.

Verwandte Themen