PHP Optimierungen

Auf der Seite PHP Benchmark gibt es eine kleine Auflistung von PHP Optimierungen, die ganz gelungen sind. Natürlich ist die Optimierung von Code bis auf die letzte Zeile übertrieben, aber es schadet nicht ein paar Regeln zu beachten.

Referenzierungsoperators &

Im ersten Test wird der Einsatz des Referenzierungsoperators & geprüft. Als Ergebnis kommt heraus, dass bei eindimensionalen Arrays der Zugriff schneller erfolgt als bei mehrdimensionalen Arrays.

$value = &$simpleArray[$i]; // Laufzeit schneller
$value = $simpleArray[$i]; // als diese Variante

Im Gegenzug zu mehrdimensionalen Arrays:

$value = &$bigArray[$a][0][0][0] // Laufzeit langsamer
$value = $bigArray[$a][0][0][0] // als diese Variante

IF und Switch

Zwischen den Varianten gibt es keinen nennenswerten Laufzeitunterschied. Lediglich bei den Vergleichen mit Typisierung (===) gab es einen kleinen Vorteil.

Einfache vs. doppelte Anführungszeichen

Bei reine Strings macht es schienbar keinen Unterschied, ob einfache oder doppelte Anführungszeichen verwendet werden. Leider stimmt das nur, solange keine Variablen innerhalb des Strings ersetzt werden müssen. Ich habe das mal ausprobiert:

"aa $x aaaa $x aaaa $x a"; // 0.000581
'aa $x aaaa $x aaaa $x a'; // 0.000160
'aa '. $x. ' aaaa '. $x. ' aaaa '. $x. ' a'; // 0.000565
echo 'aa ', $x, ' aaaa ', $x, ' aaaa ', $x, ' a'; // 0.000378

Funktionen ISSET und EMPTY UND IN_ARRAY

Auch hier gab es keinen nenneswerten Sieger. Die Funktion in_array ist teurer als die anderen zwei und sollte nur auf existierenden Variablen aufgerufen werden.

is_array($gibtsNicht); // langsam (und PHP Notice: Undefined variable)
isset($gibsNicht) && is_array($gibtsNicht) // besser

 Schleifen

Ein Funktionsaufruf im Schleifenkopf ist keine gute Idee. Die vielen Aufrufe kosten sehr viel Laufzeit.

<code>for ($i=0; $i<count($x); $i++);</code> // ganz schlecht
$count=count($x);
for ($i=0; $i<$count; $i++); // super

Außerdem kostet der Befehl list ebenfalls sehr viel Laufzeit. Meiner Meinung nach sollte man diese Funktion nicht verwenden, da der Code dadurch schlecht lesbar wird:

while(list($key) = each($hash))... // langsam und schlecht lesbar
foreach($hash as $key=>$value)... // schnell

Gegen Ende des Beitrags wurde nochmal die Schleifen bzw. die Modifikation des Array betrachtet, über das iteriert wird. Das die for-Schleife in folgender Variante so schlecht abschneidet, hat mich doch sehr verwundert:

// 425%
foreach($aHash as $key=>$val)
  $aHash[$key] .= "a"; 
 
// 100%
$key = array_keys($aHash);
$size = sizeOf($key);
for ($i=0; $i<$size; $i++)
  $aHash[$key[$i]] .= "a";

Das schlechte Ergebnis wird aber durch die Operation .= verursacht, die den bestehenden Wert mit „a“ konkateniert. Mit einer reinen Zuweisung läuft die foreach-Schleife sehr performant. Ich habe zusätzlich folgendes ausprobiert:

foreach($aHash as $key=>$val);  // 0.00001
foreach($aHash as $val);        // 0.000007
foreach($aHash as $key=>&$val); // 0.00023
foreach($aHash as &$val);       // 0.00024
foreach($aHash as $key=>$val)
  $aHash[$key] .= "a";          // 0.00024 (ursprüngliche Variante)
 
while(list($key) = each($aHash))
  $aHash[$key] .= "a";          // 0.00008 (ursprüngliche Variante)

Anmerkung: Das Array bestand ebenfalls aus 100 Elemente mit einer Schlüssellänge von 24byte und einem Wert mit 10k pro Eintrag.

Ich schätze, dass es damit zusammenhängt, dass die foreach-Schleife intern mit einer Kopie des Array arbeitet. Notiz an mich: Diesen Artikel mal genauer lesen: PHP internals: When does foreach copy?

Fazit

Ich glaube, dass die wenigsten Ergebnisse praxisrelevant sind. Bester Tip ist, dass man in Schleifenkopfen keine Funktionen aufrufen soll bzw. in Schleifen allgemein auf Funktionsaufrufe achten soll. Ein super Artikel fand ich auf ircmaxell’s blog im Artikel On Optimization in PHP. Code soll in erster Linie lesbar und somit besser warten sein. Außerdem wird dort die 90/10-Regel von R. Pattis erwähnt: „90% of a program’s execution time is spent in only 10% of its code.“. Die Kunst des Optimieres ist es also, die 10% des Codes in angemessener Zeit ausfindig zu machen…

 

 

 

Ein Gedanke zu “PHP Optimierungen

  1. Pingback: Contao 2.11.1 ist da | Tobias Seckinger

Kommentar verfassen