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.
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.
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.
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):
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ß!
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.
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.
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.
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.
Dies ist am einfachsten zu lesen, außer für ANSI C / C89, wo es ungültig ist.
Tags und Links c++