phpbar.de logo

Mailinglisten-Archive

[php] Performance-Probleme, war: Array-Funktionen vs. literale Angabe

[php] Performance-Probleme, war: Array-Funktionen vs. literale Angabe

Lutz Zetzsche Lutz.Zetzsche at sea-rescue.de
Die Feb 13 13:49:41 CET 2007


Hi Thorsten,

Thorsten Koch schrieb:
>> > (6ms vs 13ms bei 10000x[] vs 10000x array_push auf meinem Athlon 64
>> > 3700+, 2GB DDR2 Win2k php 5.2).
>
> Ein Unterschied von 7ms. Selbst bei 100k Datensätzen sinds 70ms, naja. Ich
> denke wenn man Performance-Probleme hat, dann hat man die sicherlich
> woanders und hat wirkungsvollere Stellschrauben.

Du solltest Millisekunden nicht unterschätzen. :-D

7ms für 10.000 Durchläufe, 70ms für 100.000 - und 7000ms = 7 Sekunden,
wenn das dann noch 100 Benutzer machen... ;-) Dabei ist das noch Theorie,
weil wir hier linear rechnen. Ich habe nämlich vor ein paar Wochen bei der
Optimierung meiner Website festgestellt, daß ein Flaschenhals nicht nur
für sich mehr Zeit benötigt, sondern auch dazu führt, daß nachfolgende
Programmteile merklich langsamer ausgeführt werden! So habe ich durch die
Beseitigung des Flaschenhalses nicht nur die Laufzeit an dieser Stelle
deutlich verbessert, sondern dadurch auch die des nachfolgenden Codes. :-)

Man darf sich auch nicht täuschen, was die Besucherzahlen auf der Website
angeht... :-) Aus den Besucherstatistiken werden ja die
Suchmaschinen-Spider herausgerechnet. Sie grasen aber immer wieder Deinen
Server ab. Wo ich meine Website jetzt seit ein paar Monaten im Prinzip
voll dynamisch laufen habe und mich damit erstmals richtig mit
Performanzfragen und -problemen auseinandersetzen mußte, ist mir z.B. bei
der Live-Betrachtung der Last und des Serverlogs aufgefallen, daß meine
Website permanent von teilweise mehreren Suchmaschinen gleichzeitig
besucht wird. Nur auf die lebendigen Besucher zu gucken, reicht also
nicht. Es gibt Zeiten, da habe ich alleine mindestens einen dynamischen
Seitenzugriff pro Sekunde durch Suchmaschinen. Da kommen dann die Besucher
oben drauf. Damit will ich sagen, daß man bei der Anlage seiner Website
eben schon damit rechnen muß, daß da eine Menge Zugriffe und damit Last
entsteht - und sei es nur durch Suchmaschinen. Daher macht es aus meiner
Sicht auch Sinn, bis in den Hunderstel-Bereich oder noch weiter zu
optimieren.


> Wie geht Ihr eigentlich damit um?
>
> 1. Wie findet Ihr die Bottle-Necks raus?

Ich nehme an bestimmten Punkten im Skript die Zeit und ermittele die
Laufzeit zwischen verschiedenen Messpunkten. Dort, wo besonders viel Zeit
liegen bleibt, gucke ich dann genauer.


> 2. Wie optimiert Ihr Euer System?

An erster Stelle steht bei mir immer die Datenbankoptimierung. Anständig
gesetzte Indices wirken wahre Wunder. Das Beste was ich mal vor ein paar
Monaten geschafft habe, war eine 200-fache Beschleunigung einer Abfrage
mit JOIN durch das Setzen von Indices.

Dann achte ich natürlich darauf, möglichst wenig Datenbankabfragen pro
Seite abzusetzen. Wie Du schon geschrieben hast, versuche auch ich, die
Daten aus einer Tabelle auf einmal zu ziehen und nicht für jeden Link,
jedes Foto o.ä. einzeln.

Darüber hinaus verwende ich den Smarty-Cache. Die gesamte Seite wird beim
ersten Mal dynamisch und dann aus dem Cache angezeigt.

Neuerdings setze ich auch zusätzlich Cache_Lite ein, um im PHP-Code
Funktionen zu cachen. Dazu mußte ich Cache_Lite etwas modifizieren, weil
der Funktionscache die Cache-ID zwar aus den Funktionsparametern
zusammenbaut, allerdings nicht nur aus denen der zu cachenden Funktion,
sondern auch mit den Parametern, die Cache_Lite intern hinzufügt... Damit
wird seitenabhängig gecacht, während ich einen seitenunabhängigen Cache
brauche. Ich habe also Cache_Lite so erweitert, daß ich die Cache-ID beim
Funktionscache selbst setzen kann.

Hinter dem Einsatz des Smarty-Caches und von Cache_Lite steht bei meiner
Website ein gestaffeltes, ausgeklügeltes Caching-System.

Mit Cache_Lite werden zentrale Funktionen meiner Website
seitenübergreifend gecacht, d.h. die Cache-IDs setzen sich aus den
Funktionsparametern meiner Funktionen zusammen. Dabei gibt es
Verschachtelungen, d.h. eine Funktion wird das erste Mal aufgerufen und
greift dabei auf das gecachte Ergebnis einer anderen Funktion zu. Wenn ich
mich recht erinnere, habe ich einer Stelle in meinem Code drei
Caching-Schichten übereinander, also drei aufeinander aufbauende
Funktionen, die gecacht werden.

Mit dem Smarty-Cache cache ich zum einen intern einzelne Teile einer
Seite, die auf anderen Seiten genauso vorkommen. Dadurch muß ich einen
solchen Seitenteil nur beim Aufruf der ersten Seite generieren, die diesen
Teil enthält. Auf den anderen Seiten kann ich diesen Seitenteil intern
direkt aus dem Cache einbinden und so Zeit sparen. Zum anderen cache ich
mit Smarty auch die ganze Seite, d.h. für die Seite selbst wird ebenfalls
eine eigene Cache-Datei angelegt. Wird die Seite erneut aufgerufen, wird
nur diese eine Cache-Datei benötigt. Auch bei Smarty habe ich also ein
mehrstufiges Caching-Konzept.

Das Ganze ist etwas schwierig zu erklären, aber im Prinzip läuft es darauf
hinaus, an allen Stellen, wo sich Daten nicht permanent verändern, nur
einmal dynamisch zu arbeiten und danach nur noch auf den Cache
zuzugreifen. Und dabei achte ich darauf, nicht redundant zu cachen. Auch
nicht unwichtig. :-) Das gilt für Funktionen ebenso wie für Seiteninhalte.

Ich hoffe, daß gibt Dir ein paar Denkanstöße. :-)))


Viele Grüße
Lutz


php::bar PHP Wiki   -   Listenarchive