Sie sind hier : sebastian1012.bplaced.net/ homepage-neu / kreuz-und-quer / tutorials-info-neuigkeiten-php / postfix-vs-praefix-inkrementierung.php

Postfix- vs. Präfix-Inkrementierung

Diesmal wollen wir die alte Frage, ob nun das Postfix- oder das Präfix-Inkrement schneller ist, von der C++-Welt auf PHP übertragen und kurz messen, welche Variante wir in unseren for-Schleifen nehmen sollten.

Dass das Inkrement von Haus aus schon eine eher anspruchslose Operation für den Prozessor darstellt, lassen wir es gleich 100.000.000 mal durchführen. Zum Vergleich testen wir auch noch die längeren Varianten $i += 1 und $i = $i + 1.

Das Testscript sieht folgendermaßen aus:

$before = microtime(true);   for ( $i = 0; $i < 100000000; /* Hier jeweils das Inkrement. */ ) { }   $duration = microtime(true) - $before;   echo $duration;

Nach dem Durchlauf erhalten wir folgende Ergebnisse:

Typ Gesamtlaufzeit durchschnittliche Laufzeit pro Durchlauf Verhältnis zur schnellsten Variante
Präfix 22,1 s 221 ns 100 %
Kombinierter Operator 24,6 s 246 ns 112 % (+ 12%)
Postfix 25,5 s 255 ns 116 % (+ 16%)
Lange Version 28,7 s 287 ns 130 % (+ 30%)

Wir sehen also, dass der minimale Unterschied in den Operatoren sich aus der C/C++-Welt auch hier zeigt. Die lange Version ist weit abgeschlagen (und daher sowohl aus Performance- als auch aus ästhetischen Gründen nicht empfehlenswert), während der kombinierte Operator sich erstaunlich gut schlägt und mit dem Postfix-Operator quasi gleichauf liegt.
Das Präfix-Inkrement liegt mit einem Abstand von 2,5 Sekunden mit einem ausreichendem Abstand vorn, um sagen zu können, dass es einen messbaren Unterschied gibt und PHP intern die Varianten nicht gleich behandelt.

Da der Unterschied aber nur im quasi nicht messbaren Bereich liegt (Präfix ist um 35 ns schneller als Postfix), fällt der Zeitverlust nur bei Schleifen ins „Gewicht“, die wirklich viele Millionen male durchlaufen werden müssen. Und ob bei so häufigen Durchläufen die Zeit für das Inkrement noch eine Rolle spielt, ist dann auch noch von Fall zu Fall zu entscheiden.
Auf jeden Fall kann man mit dem Präfix-Inkrement nichts falsch machen und fährt immer gut.

Hintergrund: Der Postfix-Operator gibt erst den Wert zurück und erhöht ihn danach. Daher benötigt er einen temporären Zwischenspeicher für den Wert vor dem Inkrement. Das Anlegen der Variable benötigt natürlich etwas Zeit. Da das Präfix-Inkrement erst inkrementiert und dann den Wert zurückgibt, benötigt man hier keine temporäre Variable und damit fällt auch der Zeitbedarf für das Allokieren des Speichers weg.
Zwei Beispiel-Implementierungen (aus dem wundervollen Buch „C/C++ Kompendium“ von Dirk Louis) zeigen die Unterschiede an einer fiktiven und an sich auch nutzlosen Klasse „MyInteger“:

class MyInteger { public:     int wert;       MyInteger(int i) { wert = i; }     MyInteger() { wert = 0; }       // Postfix-Inkrement     const MyInteger operator ++ (int) {         MyInteger tmp = *this;         this->wert += 1;         return tmp;     }       // Präfix-Inkrement     MyInteger& operator ++ () {         this->wert += 1;         return *this;     } }

Halten wir also fest: Immer das Präfix-Inkrement verwenden. Sieht schön aus und ist schnell.

Wie immer gibt es die verwendeten Scripts sowie die Ergebnisse zum Download.

Dieser Beitrag wurde uns freundlichst von Christoph Mewes zur Verfügung gestellt. Vielen Dank.