C ++ Deklaration von int in der for-Schleife

8

Ich habe C ++ schon lange nicht mehr benutzt. Ich bin auf meinen Java-Compiler angewiesen, um Optimierungen durchzuführen.

Was ist der am besten optimierte Weg, um eine for-Schleife in C ++ zu machen? Oder ist es jetzt gleich mit modernen Compilern? In den "alten Tagen" gab es einen Unterschied.

%Vor%

ODER

%Vor%

ODER

%Vor%

Ist es in C gleich?

BEARBEITEN: Okay, der überwältigende Konsens besteht darin, den ersten Fall zu verwenden und den Compiler zu optimieren, wenn er es möchte.

    
Yada 12.02.2010, 22:09
quelle

9 Antworten

12

Ich würde sagen, dass triviale Dinge wie diese wahrscheinlich vom Compiler optimiert werden, und Sie sollten sich nicht darum kümmern. Die erste Option ist die am besten lesbare, also sollten Sie diese verwenden.

EDIT: Hinzufügen, was andere Antworten gesagt haben, gibt es auch den Unterschied, dass, wenn Sie die Variable in der Schleife initialisieren, wird es aufhören zu existieren, nachdem die Schleife endet.

    
Javier 12.02.2010, 22:11
quelle
9

Der Unterschied ist der Umfang.

%Vor%

ist im Allgemeinen vorzuziehen, weil dann der Gültigkeitsbereich von i auf die for-Schleife beschränkt ist. Wenn Sie es vor der for-Schleife deklarieren, bleibt es bestehen, nachdem die for-Schleife beendet wurde und mit anderen Variablen kollidieren konnte. Wenn Sie es nur in der for-Schleife verwenden, gibt es keinen Grund, es länger als das zu lassen.

    
Jonathan M Davis 12.02.2010 22:12
quelle
5

Nehmen wir an, das ursprüngliche Poster hatte eine Schleife, die wirklich optimiert werden sollte - jeder Befehl wurde gezählt. Wie können wir - empirisch - die Antwort auf seine Frage herausfinden?

gcc hat zumindest einen nützlichen, wenn auch selten verwendeten Schalter,, -S '. Es speichert die Assembly-Code-Version der .c-Datei und kann verwendet werden, um Fragen wie die OP-Posen zu beantworten. Ich habe ein einfaches Programm geschrieben:

%Vor%

Und ran: gcc -O0 -std=c99 -S main.c , erstellt die Assembly-Version des Hauptprogramms. Hier ist der Inhalt von main.s (mit einigen der Flusen entfernt):

%Vor%

Sie müssen kein Montageexperte sein, um herauszufinden, was vor sich geht. Movl verschiebt Werte, addl fügt Dinge hinzu, cmpl vergleicht und jle steht für 'springen wenn kleiner als', $ ist für Konstanten. Es lädt 0 in etwas - das muss "Summe" sein, 1 in etwas anderes - ah, "ich"! Ein Sprung zu L2, wo wir den Vergleich mit 10 machen, springe zu L3, um das Add zu machen. Gehe nochmal zu L2 um den Vergleich zu wiederholen. Ordentlich! Eine for-Schleife.

Ändern Sie das Programm zu:

%Vor%

Führen Sie gcc erneut aus, und die resultierende Assembly wird sich sehr ähneln. Es gibt einige Dinge, die mit der Aufzeichnung von Zeilennummern passieren, also werden sie nicht identisch sein, aber die Assembly ist die gleiche. Gleiches Ergebnis mit dem letzten Fall. Also, auch ohne Optimierung ist der Code ungefähr gleich.

Aus Spaß, führen Sie gcc mit '-O3' anstelle von '-O' erneut aus, um die Optimierung zu aktivieren und sehen Sie sich die .s-Datei an.

%Vor%

gcc hat nicht nur herausgefunden, dass wir eine for-Schleife machen, sondern haben auch gemerkt, dass es eine konstante Anzahl von Wiederholungen der Schleife für uns zur Kompilierzeit ausgeführt wurde, "i" und "sum" und hart codiert Antwort - 55! Das ist SCHNELL - wenn auch ein bisschen erfunden.

Moral der Geschichte? Verbringen Sie Ihre Zeit damit, sicherzustellen, dass Ihr Code sauber und gut gestaltet ist. Code für Lesbarkeit und Wartbarkeit. Die Jungs, die von Mountain Dew und Cheetos leben, sind viel schlauer als wir und haben die meisten dieser einfachen Optimierungsprobleme für uns erledigt. Viel Spaß!

    
Jesse K 13.02.2010 03:09
quelle
4

Es ist dasselbe. Der Compiler wird diese für die gleiche Sache optimieren.

Selbst wenn sie nicht gleich wären, wäre der Unterschied zum tatsächlichen Körper Ihrer Schleife vernachlässigbar. Sie sollten sich keine Gedanken über solche Mikrooptimierungen machen. Und Sie sollten keine Mikrooptimierungen vornehmen, es sei denn, Sie erstellen Leistungsprofile, um festzustellen, ob dies tatsächlich einen Unterschied macht.

    
Mark Byers 12.02.2010 22:10
quelle
3

Gleiches gilt für die Geschwindigkeit. Der Compiler wird optimiert, wenn Sie i nicht später verwenden.

Im Hinblick auf Stil - Ich würde die Definition in das Schleifenkonstrukt setzen, da es das Risiko verringert, dass Sie in Konflikt geraten, wenn Sie später ein anderes i definieren.

    
Uri 12.02.2010 22:12
quelle
1

Mach dir keine Sorgen über Mikrooptimierungen, lass den Compiler das machen. Wählen Sie, was am besten lesbar ist. Beachten Sie, dass die Deklaration einer Variablen in einer for Initialisierungsanweisung die Variable auf die for -Anweisung beschränkt (C ++ 03 § 6.5.3 1 ), obwohl das genaue Verhalten der Compiler variieren kann (einige lassen Sie sich aussuchen). Wenn Code außerhalb der Schleife die Variable verwendet, deklarieren Sie sie außerhalb der Schleife. Wenn die Variable wirklich lokal für die Schleife ist, deklarieren Sie sie im Initialisierer.

    
outis 12.02.2010 22:14
quelle
1

Es wurde bereits erwähnt, dass der Hauptunterschied zwischen beiden der Anwendungsbereich ist. Stellen Sie sicher, dass Sie verstehen, wie Ihr Compiler den Gültigkeitsbereich eines int als

deklariert %Vor%

Ich weiß, dass ich bei der Verwendung von MSVC ++ 6 immer noch außerhalb der Schleife bin, als ob es vor der Schleife deklariert wäre. Dieses Verhalten unterscheidet sich von VS2005, und ich müsste überprüfen, aber ich denke, die letzte Version von gcc, die ich verwendet habe. In beiden Compilern war diese Variable nur innerhalb der Schleife enthalten.

    
Jeff Barger 12.02.2010 22:41
quelle
1
%Vor%

Dies ist am einfachsten zu lesen, außer für ANSI C / C89, wo es ungültig ist.

    
TommyGunn32 14.02.2011 22:31
quelle
-1

Es ist alles gleich.

    
rmn 12.02.2010 22:14
quelle

Tags und Links