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".
<?php
if($a==$b){ }
// unteres ist schneller als oberes
if($a===$b){ }
?>
Dasselbe gilt auch für !=.
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.
oberes:   82 ms
unteres:  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().
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 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(123);
?>
Die beiden Aufrufe machen genau das gleiche, doch ist die obere Variante ohne Parametern schneller.
func():     12.5 ms
func(...):  14.5 ms

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.
 


Andere Einträge


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

#3
von max am 29.05.2012
Super Zusammenfassung! Vor allem mit echten Belegen!
Eine Frage hätte ich: Ist die Suche nach dem Key oder nach der Value in nem Array schneller?
VG

#4
von Floern am 31.05.2012
@max: Die Suche nach einem Key ist deutlich schneller als nach einem Wert.

#5
von CHris am 28.07.2012
Wow, sehr ausführliche Liste, ich werde gleich mal den einen oder anderen Tipp ausprobieren, danke!

#6
von Ralf am 05.08.2012
Prima Zusammenstellung.... danke... da ich gerade meine Webseite wegen Timing-Problemen neu aufsetze, kommt das gerade wie gerufen :-)

#7
von NovaTech2010 am 16.01.2013
Diese Tipps haben meiner Website mehr als 4 Sekunden mehr gegeben ^^
Vielen Dank!

#8
von NovaTech2010 am 16.01.2013
Nein ich meinte natürlich 4 Millisekunden >_<
Und tschuldigung wegen dem Spamkommentar D:

#9
von NovaTech2010 am 30.01.2013
Ich kann einen Tipp beitragen:
is_dir und is_file sind beide schneller als file_exists. Dieser Kommentar kann ruhig übernommen und gelöscht werden o:

#10
von Trekkster am 05.04.2013
Zu Punkt 15 gibt es aber auch andere AUssagen:

http://cznp.com/blog/3/strtr-vs-str_replace-a-battle-for-speed-and-dignity

#11
von TC am 19.07.2013
hallo, ist Array oder Switch schneller? Beispiel: ein wert ist in einer db gespeichert, mit Switch oder eben einem Array wird ausgegeben was der wert bedeutet. 1 = grün, 2 = blau usw. ??? mfg

#12
von Peet am 13.02.2014
Super artikel, nette Analyse. Die array_map() Funktion war mir noch nicht bekannt echt super das ding, spart einiges an Aufwand!

#13
von Jakob Rohländer am 23.05.2014
Danke, tolle Zusammenfassung

#14
von Björn Kohlsdorf am 31.05.2015
Anmerkung zu Punkt 13: ++$i; ist schneller als $i++;
Da so $i erst nach der Inkrementierung in den Speicher geladen wird, statt erst in Speicher zu kommen, von dort ausgelesen wird, inkrementiert und zurück geschrieben. Spart ca. 1ms bei 100.000 Durchläufen. Yeah! :)