Geschwindigkeit von PHP-Scripts optimieren
Folgende Aufzählung enthält Tipps und Tricks zur Steigerung der Ausführungsgeschwindigkeit von PHP-Scripts.
1. "Identisch" ist schneller als "gleich"
<?php
if ($a == $b) { }
// unteres ist schneller als oberes
if ($a === $b) { }
?>
Dasselbe gilt auch für !=
vs !==
.
gleich: 15.5 ms
identisch: 9.0 ms
2. "Identisch" ist schneller als "nicht identisch"
<?php
if ($a === true) { }
// oberes ist schneller als unteres
if ($a !== false) { }
?>
identisch: 8.5 ms
nicht identisch: 9.5 ms
Bei einem einfachen "gleich" (==
bzw. !=
) ist kaum ein Unterschied festzustellen.
3. "Kleiner gleich" ist schneller als "kleiner als"
<?php
if ($i < 10) { }
// unteres ist schneller als oberes
if ($i <= 9) { }
?>
kleiner als: 16.0 ms
kleiner gleich: 14.5 ms
Andersherum ist "grösser als" ist leicht schneller als "grösser gleich".
<?php
if ($i > 9) { }
// oberes ist schneller als unteres
if ($i >= 10) { }
?>
grösser als: 14.4 ms
grösser gleich: 15.0 ms
4. Der Trinitäts-Operator ist schneller als ein einfaches if-else-Statement
<?php
if ($b) { $a = $c; }
else { $a = $d; }
// unteres ist schneller als oberes
$a = ($b) ? $c : $d;
?>
if-else-Statement: 18.3 ms
Trinitäts-Operator: 11.5 ms
5. Fehlermeldungen nicht mit einem @
unterdrücken
<?php
// nicht so:
@unlink('mich-gibts-nicht.dat');
// sondern so:
if (file_exists('mich-gibts-nicht.dat'))
unlink('mich-gibts-nicht.dat');
?>
6. Fehlermeldungen, Notices und Strict-Standards nicht unterdrücken, sondern verhindern
<?php
// nicht so:
$wert = array_shift(explode($str, $array)); // erzeugt eine Strict-Meldung
// sondern so:
$werte = explode($str, $array));
$wert = array_shift($werte);
// ----
// nicht so:
if ($gibtsnicht) { } // erzeugt eine Notice
// sondern so:
if (isset($gibtsnicht)) { }
?>
Fehlermeldungen jeglicher Art, ob sie unterdrückt werden oder nicht, verlangsamen das Script.
7. (int)
ist mehr als doppelt so schnell wie intval()
<?php
$zahl = intval($str);
// unteres ist schneller als oberes
$zahl = (int)$str;
?>
intval()
bietet noch eine zusätzliche Funktion, welche jedoch meist nicht benutzt wird.
intval(): 53 ms
(int): 25 ms
8. Einfache Anführungszeichen und Stringverkettung benutzen
<?php
echo "Ich heisse $name";
// unteres ist schneller als oberes
echo 'Ich heisse '.$name;
?>
Da PHP bei doppelten Anführungszeichen den String nach Variablen durchsucht, geht da Zeit verloren.
doppelt: 82 ms
einfach: 70 ms
9. echo ist schneller als print
<?php
echo 'Text';
// oberes ist schneller als unteres
print 'Text';
?>
print
hat im Gegensatz zu echo
einen Rückgabewert, doch dieser ist im Grunde nutzlos.
echo: 23 ms
print: 31 ms
10. Stringverkettung ist langsamer als mehrere echos (bei mehreren Variablen)
<?php
echo $var1.$var2.$var3.$var4.$var5;
// unteres ist geringfügig schneller als oberes
echo $var1; echo $var2; echo $var3; echo $var4; echo $var5;
echo $var1, $var2, $var3, $var4, $var5;
?>
Wenn nur mehrere Strings (keine Variablen) ausgegeben werden, gibt es keinen Unterschied.
Verkettung: 25 ms
mehrere echo: 20 ms
Komma-getrennt: 20 ms
11. array_map()
ist schneller als foreach
<?php
$array = array_map('funktion', $array);
// oberes ist schneller als unteres
foreach($array as &$value)
$value = funktion($value);
?>
Bei Arrays mit weniger als 15 Elementen empfiehlt es sich jedoch foreach zu benutzen.
array_map(): 72 ms
foreach: 90 ms
Anmerkung: Der effektive Unterschied der Geschwindigkeit der beiden Methoden ist von der Funktion abhängig, welche auf die Array-Werte angewendet wird.
12. Funktionen innerhalb von Schleifen-Parametern sind sehr kostspielig
<?php
// nicht so:
for ($i = 0; $i < count($array); $i++) { }
// sondern so:
$total = count($array);
for ($i = 0; $i < $total; $i++) { }
?>
oberes: 53 ms
unteres: 18 ms
Bei der oberen Methode muss die Funktion (hier count()
) pro Durchgang einmal ausgeführt werden,
bei der unteren wird sie insgesamt nur einmal aufgerufen.
13. $i++
ist schneller als $i+=1
$i++: 8.5 ms
$i+=1: 9.5 ms
14. $array[]
ist schneller als array_push()
<?php
$array[] = 'value';
// oberes ist schneller als unteres
array_push($array, 'value');
?>
$array[]: 60 ms
array_push(): 102 ms
15. strtr()
ist schneller als str_replace()
, dieses ist schneller als preg_replace()
... und dieses wiederum ist schneller als ereg_replace()
, allerdings empfiehlt es sich,
ganz auf ereg
-Funktionen zu verzichten.
16. Benutze unset()
um den Speicher wieder freizugeben
Dies lohnt sich allerdings nur bei grösseren Variablen wie längeren Strings oder Arrays.
Bei MySQL-Daten kann man mysql_free_result()
verwenden.
17. Includes (include()
, require()
) sollten wenn möglich verhindert werden
Jeder Include verursacht ein erneuter Zugriff auf das Dateisystem und somit zusätzliche Festplattenaktivität. Des weiteren muss der PHP-Parser nochmal ans Werk.
Falls eine nicht-PHP-Datei eingebunden werden muss, empfiehlt es sich readfile()
zu benutzen.
18. htmlspecialchars()
ist schneller als htmlentities()
Wenn man nur die HTML/XML-Steuerzeichen als Entities kodieren will, ist es angebracht
htmlspecialchars()
zu verwenden.
htmlspecialchars(): 80 ms
htmlentities(): 150 ms
Der Geschwindigkeitsunterschied ist nachvollziehbar.
19. Optionaler Parameter nicht an Funktion übergeben, wenn er dem Standard-Wert entspricht
<?php
function func($a=1, $b=2, $c=3) {
// Beispiel-Funktion mit optionalen Parametern
}
// Aufruf ohne Parameter:
func();
// Aufruf mit den Standard-Werten:
func(1, 2, 3);
?>
Die beiden Aufrufe machen genau das gleiche, doch ist die obere Variante ohne Parametern schneller.
func(): 12.5 ms
func(...): 14.5 ms
Testmethode
Die Tests wurden unter Windows XP bei PHP 5.2.3 durchgeführt, mittels einer
for
-Schleife mit 100'000 oder 10'000 Durchläufen. Die Werte sind Durchschnittswerte von
ca. 30 Einzel-Ergebnissen. Von den Werten wurde jeweils die Leerlaufzeit der for
-Schleife abgezogen.
Kommentar
In den meisten Fällen ist Leserlichkeit des Codes wichtiger als Geschwindigkeit, deshalb sei es gut überlegt ob man Code durch performanteren aber weniger leserlichen ersetzt.