Geschwindigkeit von PHP-Scripts optimieren
Oktober 2009
Folgende Aufzählung enthält Tipps und Tricks zur Steigerung der Ausführungsgeschwindigkeit von PHP-Scripts.
1. "Identisch" ist schneller als "gleich".
2. "Identisch" ist schneller als "nicht identisch".
3. "Kleiner gleich" ist schneller als "kleiner als".
4. Der Trinitäts-Operator ist schneller als ein einfaches if-else-Statement.
5. Fehlermeldungen nicht mit einem @ unterdrücken.
6. Fehlermeldungen, Notices und Strict-Standards nicht unterdrücken sondern verhindern.
7. (int) ist mehr als doppelt so schnell wie intval().
8. Einfache Anführungszeichen und Stringverkettung benutzen.
9. echo ist schneller als print.
10. Stringverkettung ist langsamer als mehrere echos (bei mehreren Variablen)
11. array_map() ist schneller als foreach.
12. Funktionen innerhalb von Schleifen-Parametern sind sehr kostspielig.
13. $i++ ist schneller als $i+=1.
14. $array[] ist schneller als array_push().
15. strtr() ist schneller als str_replace(), dieses ist schneller als preg_replace() und dieses wiederum ist schneller als ereg_replace().
Des Weiteren 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, da jeder Include ein erneuter Zugriff auf das Dateisystem und somit zusätzliche Festplattenaktivität bewirkt und der PHP-Parser nochmal ans Werk muss.
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.
19. Optionaler Parameter nicht an Funktion übergeben, wenn er dem Standard-Wert entspricht.
Anmerkung: 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.
1. "Identisch" ist schneller als "gleich".
<?php
if($a==$b){ }
// unteres ist schneller als oberes
if($a===$b){ }
?>Dasselbe gilt auch für !=.gleich: 15.5 ms
identisch: 9.0 ms2. "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 msBei 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 msAndersherum 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 ms4. 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 ms5. 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 ms8. 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.oberes: 82 ms
unteres: 70 ms9. 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 ms10. 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 ms11. 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 msAnmerkung: 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 msBei 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 ms14. $array[] ist schneller als array_push().
<?php
$array[] = 'value';
// oberes ist schneller als unteres
array_push($array, 'value');
?>$array[]: 60 ms
array_push(): 102 ms15. strtr() ist schneller als str_replace(), dieses ist schneller als preg_replace() und dieses wiederum ist schneller als ereg_replace().
Des Weiteren 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, da jeder Include ein erneuter Zugriff auf das Dateisystem und somit zusätzliche Festplattenaktivität bewirkt und der PHP-Parser nochmal ans Werk muss.
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 msDer 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 msAnmerkung: 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.
Andere Einträge
- Undercover-MSN-Bot aufdecken
- Herkunftsland des Besuchers ermitteln
- PHP Mikro-Optimierungen und Benchmarks
- Dateien mit .htaccess gzip komprimieren
- HTML-Highlighter
Kommentare
#1
von romacron am 22.11.2009
Das ist mal ne gute Idee, wenn man diese Kleinigkeiten im Kopf hat ist das für die Geschwindigkeits-Junkies genau das Richtige.
#2
von Heiko am 15.04.2010
Das nenne ich mal eine super Zusammenstellung. Gerade beim Punkt 14 konnte ich einen richtigen Performance-Gewinn erziehlen. Danke