Gibt es einen Leistungsunterschied zwischen i++
y ++i
wenn der resultierende Wert nicht verwendet wird?
Antworten
Zu viele Anzeigen?In C kann der Compiler sie im Allgemeinen so optimieren, dass sie gleich sind, wenn das Ergebnis unbenutzt ist.
Wenn in C++ jedoch andere Typen verwendet werden, die ihre eigenen ++-Operatoren anbieten, ist die Präfix-Version wahrscheinlich schneller als die Postfix-Version. Wenn Sie also die Postfix-Semantik nicht benötigen, ist es besser, den Präfix-Operator zu verwenden.
Ich kann mir eine Situation vorstellen, in der Postfix langsamer ist als Präfix-Inkrement:
Stellen Sie sich einen Prozessor mit Register A
wird als Akkumulator verwendet und ist das einzige Register, das in vielen Anweisungen verwendet wird (einige kleine Mikrocontroller sind tatsächlich so).
Stellen Sie sich nun das folgende Programm und seine Übersetzung in eine hypothetische Baugruppe vor:
Präfix-Inkrement:
a = ++b + c;
; increment b
LD A, [&b]
INC A
ST A, [&b]
; add with c
ADD A, [&c]
; store in a
ST A, [&a]
Postfix-Inkrement:
a = b++ + c;
; load b
LD A, [&b]
; add with c
ADD A, [&c]
; store in a
ST A, [&a]
; increment b
LD A, [&b]
INC A
ST A, [&b]
Beachten Sie, dass der Wert von b
musste neu geladen werden. Bei der Präfix-Inkrementierung kann der Compiler den Wert einfach inkrementieren und mit der Verwendung fortfahren, wobei ein Neuladen möglicherweise vermieden wird, da sich der gewünschte Wert nach der Inkrementierung bereits im Register befindet. Beim Postfix-Inkrement hingegen muss der Compiler mit zwei Werten umgehen, einem alten und einem inkrementierten Wert, was, wie ich oben gezeigt habe, einen weiteren Speicherzugriff zur Folge hat.
Wenn der Wert des Inkrements nicht verwendet wird, wie z. B. bei einem einzelnen i++;
Anweisung kann der Compiler einfach eine Inkrement-Anweisung erzeugen (und tut dies auch), unabhängig von der Verwendung von Postfix oder Präfix.
Als Randbemerkung möchte ich erwähnen, dass ein Ausdruck, in dem es eine b++
kann nicht einfach in eine mit ++b
ohne zusätzlichen Aufwand (zum Beispiel durch Hinzufügen einer - 1
). Daher ist ein Vergleich der beiden, wenn sie Teil eines Ausdrucks sind, nicht wirklich gültig. Oft, wenn Sie b++
innerhalb eines Ausdrucks können Sie nicht verwenden ++b
also selbst wenn ++b
potenziell effizienter wäre, wäre es einfach falsch. Die Ausnahme ist natürlich, wenn der Ausdruck darum bettelt (zum Beispiel a = b++ + 1;
die geändert werden kann in a = ++b;
).
Ich bevorzuge jedoch immer die Vorerhöhung ...
Ich wollte darauf hinweisen, dass der Compiler auch im Falle des Aufrufs der Funktion operator++ in der Lage ist, das Provisorium wegzuoptimieren, wenn die Funktion inlined wird. Da der Operator++ in der Regel kurz ist und oft im Header implementiert wird, ist es wahrscheinlich, dass er inlined wird.
In der Praxis gibt es also wahrscheinlich keinen großen Unterschied zwischen der Leistung der beiden Formen. Ich bevorzuge jedoch immer Pre-Increment, da es besser scheint, direkt auszudrücken, was ich zu sagen versuche, anstatt sich auf den Optimierer zu verlassen, um es herauszufinden.
Wenn der Optmizer weniger zu tun hat, läuft der Compiler wahrscheinlich auch schneller.
Mein C ist ein wenig eingerostet, also entschuldige ich mich im Voraus. Was die Geschwindigkeit betrifft, kann ich die Ergebnisse verstehen. Aber ich bin verwirrt, wie beide Dateien den gleichen MD5-Hash erhalten haben. Vielleicht läuft eine for-Schleife gleich ab, aber würden die folgenden 2 Codezeilen nicht unterschiedliche Assemblierungen erzeugen?
myArray[i++] = "hello";
gegen
myArray[++i] = "hello";
Die erste schreibt den Wert in das Array und inkrementiert dann i. Die zweite inkrementiert i und schreibt dann in das Array. Ich bin kein Assembler-Experte, aber ich verstehe einfach nicht, wie die gleiche ausführbare Datei durch diese 2 verschiedenen Codezeilen erzeugt werden kann.
Nur meine Meinung dazu.
- See previous answers
- Weitere Antworten anzeigen