C / C ++: Ist GOTO schneller als WHILE und FOR?

7

Ich weiß, dass jeder GOTO hasst und niemand empfiehlt es. Aber darum geht es nicht. Ich möchte nur wissen, welcher Code der schnellste ist:

  1. die goto Schleife

    %Vor%
  2. die while Schleife

    %Vor%
  3. die for Schleife

    %Vor%
Artur Iwan 20.03.2011, 05:22
quelle

8 Antworten

12

Im Allgemeinen werden for und while Schleifen auf die gleiche Weise wie goto kompiliert, so dass es normalerweise keinen Unterschied macht. Wenn Sie Zweifel haben, können Sie alle drei ausprobieren und sehen, was länger dauert. Wahrscheinlichkeiten sind, dass Sie einen Unterschied nicht messen können, selbst wenn Sie eine Milliarde Schleifen wiederholen.

Wenn Sie diese Antwort , Sie werden sehen, dass der Compiler genau den gleichen Code für for , while und goto generieren kann (nur in diesem Fall gab es keine Bedingung) .

    
Gabe 20.03.2011, 05:27
quelle
6

Schreiben Sie kurze Programme, dann tun Sie das:

%Vor%

Analysieren Sie die Ausgabe und sehen Sie, ob es einen Unterschied gibt. Stellen Sie sicher, ein gewisses Maß an Unvorhersehbarkeit einzuführen, so dass der Compiler das Programm nicht zu nichts optimiert.

Die Compiler optimieren diese trivialen Probleme auf hervorragende Weise. Ich schlage vor, dass ich mir keine Sorgen machen muss, und konzentriere mich darauf, was dich als Programmierer produktiver macht.

Geschwindigkeit und Effizienz sind eine großartige Sache, um sich darum zu sorgen, aber 99% der Zeit, die die Verwendung von geeigneten Datenstrukturen und Algorithmen erfordert ... keine Sorge darüber, ob ein for schneller ist als ein while oder ein goto usw.

    
Matthew 20.03.2011 05:39
quelle
4
Das einzige Mal, dass ich das Argument für goto gesehen habe, war in einem von W. Richard Stevens Artikeln oder Büchern. Sein Punkt war, dass in einem sehr zeitkritischen Codeabschnitt (ich glaube, sein Beispiel war der Netzwerkstapel) geschachtelt wurde, wenn / else-Blöcke mit zugehörigem Fehlerbehandlungscode mit goto in a erneut erstellt werden konnten Weg, der einen wertvollen Unterschied machte.

Ich persönlich bin nicht gut genug, um mit Stevens Arbeit zu argumentieren, also werde ich es nicht versuchen. goto kann für leistungsbezogene Probleme nützlich sein, aber die Grenzen von wenn das ist, sind ziemlich streng.

    
Harper Shelby 20.03.2011 05:31
quelle
3

Es ist wahrscheinlich sowohl Compiler, Optimierer als auch architekturspezifisch.

Zum Beispiel ist der Code if(--i) goto loop; ein konditionaler Test gefolgt von einem unbedingten Zweig . Ein Compiler könnte einfach den entsprechenden Code erzeugen oder er wäre schlau genug (obwohl ein Compiler, der nicht über so viel Intelligenz verfügte, möglicherweise nicht viel wert ist), um eine einzelne bedingte Verzweigung zu erzeugen. while(i--) andererseits ist bereits eine bedingte Verzweigung auf der Quellenebene, so dass die Übersetzung in eine bedingte Verzweigung auf der Maschinenebene einfacher sein kann, unabhängig von der Komplexität der Compilerimplementierung oder des Optimierers.

Am Ende ist der Unterschied wahrscheinlich klein und nur relevant, wenn sehr viele Iterationen erforderlich sind, und die Art, wie Sie diese Frage beantworten sollten, besteht darin, den Code für das spezifische Ziel und den Compiler (und die Compilereinstellungen) zu erstellen Interesse, und entweder den resultierenden Code auf Maschinenebene zu inspizieren oder die Ausführungszeit direkt zu messen.

In Ihren Beispielen dominiert printf () in der Schleife jedes Timing; Etwas einfacher in der Schleife würde Beobachtungen der Unterschiede einfacher machen. Ich würde eine leere Schleife vorschlagen und dann i volatile deklarieren, um zu verhindern, dass die Schleife auf nichts optimiert wird.

    
Clifford 20.03.2011 11:17
quelle
2

Solange Sie den gleichen Kontrollfluss wie eine normale Schleife erzeugen, kann und wird fast jeder vernünftige Compiler den gleichen Code erzeugen, egal ob Sie for , while usw. dafür verwenden.

Sie können etwas mit goto erreichen, aber normalerweise nur, wenn Sie einen Kontrollfluss erzeugen, den eine normale Schleife einfach nicht (zumindest sauber) ausführen kann. Ein typisches Beispiel ist das Springen in die Mitte einer Schleife, um ein Schleifen-and-Half-Konstrukt zu erhalten, das die normalen Schleifenanweisungen der meisten Sprachen (einschließlich Cs) nicht sauber bereitstellen.

    
Jerry Coffin 20.03.2011 06:05
quelle
2

Es sollte keinen signifikanten Unterschied zwischen allen Loops und dem Goto geben. Außer der Idee wird dieser Compiler wahrscheinlich nicht versuchen, die GOTO-Dinge überhaupt zu optimieren.

Und es ist nicht sehr sinnvoll, Compiler-generierte Sachen in Loops zu optimieren. Es ist sinnvoller, den Code innerhalb der Schleife zu optimieren oder die Anzahl der Iterationen zu reduzieren.

    
voidlizard 20.03.2011 07:04
quelle
1

Ich denke, dass es unter dem nornalen Zustand einen Code nach dem Compiler geben wird.

Tatsächlich finde ich, dass es manchmal sehr bequem ist, obwohl es schwer zu lesen ist.

    
Alan Tam 21.03.2011 10:49
quelle
0

Es gibt einige Nischenvertikale, in denen goto immer noch als Standardpraxis verwendet wird, von einigen sehr sehr schlauen Leuten und es gibt keine Voreingenommenheit gegen goto in diesen Einstellungen. Ich arbeitete früher in einer simulationsorientierten Firma, in der der gesamte lokale Fortran-Code Unmengen von GOTOS enthielt, das Team war sehr schlau und die Software arbeitete nahezu fehlerfrei.

Also können wir das Verdienst von goto beiseite lassen, und wenn die Frage nur darin besteht, die Schleifen zu vergleichen, dann tun wir dies durch Profilieren und / oder Vergleichen des Assembler-Codes. Allerdings enthält die Frage auch Aussagen wie printf usw. Sie können sich nicht wirklich über die Optimierung der Schleifensteuerungslogik unterhalten. Wie bereits erwähnt, erzeugen die gegebenen Schleifen sehr ähnliche Maschinencodes.

Alle bedingten Verzweigungen werden in Pipeline-Prozessorarchitekturen sowieso als "genommen" (wahr) betrachtet, bis die Decodierungsphase, zusätzlich zu kleinen Schleifen, die normalerweise so erweitert werden, dass sie ohne Schleifen sind. Also, in Übereinstimmung mit Harpers obigen Punkt, ist es unrealistisch, dass goto bei der einfachen Schleifenkontrolle irgendeinen Vorteil hat (genauso wie für oder während sie keinen Vorteil gegenüber einander haben). GOTO macht normalerweise in mehreren verschachtelten Schleifen oder mehreren verschachtelten ifs Sinn, wenn die zusätzliche Bedingung, die von goto in JEDEN der verschachtelten Schleifen oder verschachtelten ifs geprüft wird, suboptimal ist.

Wenn Sie eine Suchoperation in einer einfachen Schleife optimieren, ist die Verwendung eines Sentinals manchmal effektiver als alles andere. Im Wesentlichen können Sie durch Hinzufügen eines Dummy-Werts am Ende des Arrays vermeiden, dass zwei Bedingungen (Array-Ende und gefundener Wert) als nur eine Bedingung (Wert gefunden) überprüft werden, und das speichert Cmp-Vorgänge intern. Ich bin mir nicht bewusst, ob Compiler das automatisch tun oder nicht.

    
Josh 21.03.2011 02:10
quelle

Tags und Links