Weg zur Seite:  
Geschwister:  
Kinder:  

Sonstiges:
Externe Links:



Hier nun ein paar Tipps, was man beachten sollte, um nicht seine eigenen Programme auszubremsen.
Dies sind meist Kleinigkeiten, aber es summiert sich. Und wer auch bei Kleinigkeiten schon auf die Performance achtet, der wird dies auch eher an kritischen Stellen tun.
Alle Angeben beziehen sich, soweit nicht anders genannt, auf PHP4.

Welche Schleife ist am schnellsten?

Gerade bei Schleifen ist es besonders wichtig auf die Performance zu achten. Denn in der Natur von Schleifen liegt es, daß die Schleife selbst und Ihr enthaltener Code mehrfach ausgeführt werden. D.h. hier summiert sich ein Zeitverlust oder Zeitgewinn bei jedem Durchlauf.

Die for- und die while-Schleife arbeiten unter PHP4 etwa in derselben Geschwindigkeit (unter PHP3 ist die for-Schleife etwas langsamer). Bezüglich ihrer Einsatzmöglichkeiten sind sie ebenfalls identisch. Ich bevorzuge die for-Schleife, da deren Notierung weniger Zeilen benötigt.

Geht man schrittweise durch ein Array, so bietet sich der angenehmen Benutzung wegen die foreach-Schleife an. Diese ist jedoch, sowohl bei kontinuierlich indizierten Arrays (Indixes: 0, 1, 2, 3 etc.) als auch bei assoziativen Arrays (Zeichenketten als Schlüssel, z.b. $lastname['Bodo'] = 'Kälberer';) der for- bzw. while-Schleife deutlich unterlegen.
Beispiel 1.a:

 $letters = array( 'A', 'B', 'C', 'D', 'E', 'F' ); $count = count( $letters ); for ( $i = 0; $i < $count; $i++ ) {
        $letter= $letters[$i];
    }

    foreach ( $letters as $letter ) {
    }
 
Hier ist die erste Schleife fast doppelt so schnell.

Dies ändert sich (erstaunlicher Weise) auch dann nicht, wenn wir aus $letters ein assoziatives Array machen.
Beispiel 1.b:
 $letters = array( 'a' => 'A', 'b' => 'B', 'c' => 'C', 'd' => 'D', 'e' => 'E', 'f' => 'F' ); $keys = array_keys( $letters ); $count = count( $keys ); for ( $i = 0; $i < $count; $i++ ) {
        $letter    = $letters[$keys[$i]];
    }

    foreach ( $letters as $letter ) {
    }
 
Auch hier benötig die zweite Schleife rund 80% mehr Zeit als die erste.

Die foreach-Schleife ist also da sehr nützlich, wo es um die Übersichtlichkeit geht (das zeigt das Beispiel 1.b sehr gut), sollte jedoch da vermieden werden, wo es auf die Geschwindigkeit ankommt.

Die foreach-Schleife hat neben der Geschwindigkeit auch den Nachteil, daß über die den Wert beinhaltenden Variable ($letter) kein schreibender Zugriff auf das Array möglich ist. Ändert man den Wert von $letter, so ändert sich der entsprechende Wert des Arrays nicht. Ändert man hingegen den Wert von $letters[$i], so wird der Wert im Array selbst geändert.

Einfache oder doppelte Anführungszeichen?

In PHP kann man Zeichenketten entweder mit einfachen Anführungszeichen (') oder mit doppelten (") umschliessen.
Der Unterschied dabei ist, daß in Zeichenketten, die mittels einfacher AZs. umfaßt werden, keine weitere Bearbeitung der Zeichenkette stattfindet. D.h. hier werden weder Escape-Characters (z.B. \n) aufgelöst, noch Variablen durch ihre Werte ersetzt.
Beispiel 2.a:

 $minimum = 18; echo 'Das Mindestalter ist:\n$minimum'; echo "\n"; echo "Das Mindestalter ist:\n$minimum"; 
Ergibt als Ausgabe:
 Das Mindestalter ist:\n$minimum Das Mindestalter ist: 18 

Zeichenketten in einfachen AZs. müssen also nicht extra ausgewertet werden, was den Programmablauf beschleunigt. Kommen in den Zeichenketten keine Variablen vor, so optimiert PHP die Verarbeitung intern und macht dadurch den Unterschied wett (zumindest wenn der Code innerhalb von Schleifen mehrmals verwendet wird).
Dazu Beispiel 2.b:
 $name = 'Siegesmund'; $age = 43; # Fall 1: $text = "Der Name der Person ist $name.\nSie ist $age Jahre alt."; # Fall 2: $text = "Der Name der Person ist ".$name.".\nSie ist ".$age." Jahre alt."; # Fall 3: $text = 'Der Name der Person ist '.$name.".\n".'Sie ist '.$age.' Jahre alt.'; 
In allen drei Fällen enthält $text nach Ausführung der Zuweisung exakt denselben Wert. Jedoch hat die Zuweisung unterschiedlich viel Zeit in Anspruch genommen. Auf meinem System ergeben sich für eine 500.000-malige Durchführung jeder Zuweisung folgende Zeiten:
  Fall 1: 14 Sekunden
  Fall 2: 5 Sekunden
  Fall 3: 5 Sekunden
Ein durchaus beachtlicher Unterschied.
Mit PHP3 sind die Zeiten übrigens: 17, 20 und 15 Sekunden.

Auch hier lohnt es sich also, ein Gleichgewicht zwischen Lesbarkeit und Performance finden.

Die Länge von Variablen und Funktionsnamen

Auch die Länge von Variablen und Funktionsnamen wirkt sich, allerdings in eher geringem Maße, auf die Geschwindigkeit aus.
Wer als Namen für eine Variable z.B. $name statt $nameOfThePersonHandledRightNow wählt, der spart dabei rund 15% Zeit ein. Für Schleifen also durchaus bedenkenswert. Solange man dabei nicht vergißt, daß aussagekräftige Variablennamen für das die Lesbarkeit des Codes wichtig sind.
Auch die Länge von Funktionsnamen schlägt im einstelligen Prozentbereich zu Buche.

Verwendung von Hilfsvariablen

Mit Hilfsvariablen meine ich Variablen, die für den Moment Werte übernehmen um einen Vorgang (z.B. einen Vergleich) zu erleichtern oder zu beschleunigen, deren Wert jedoch nicht über den Moment hinaus von Bedeutung ist.
Diese nehmen z.B. das Ergebnis von komplexen Rechenoperationen auf, die sonst mehrfach gemacht werden müßten. Oder sie übernehmen den Wert eines Elements aus einem Array, auf den mehrfach zugegriffen wird und sparen dadurch die Zeit, die intern gebraucht wird, um den Wert immer wieder neu zu finden.
Beispiel 3.a:

 $text = 'abcdefghijklmnopqrstuvwxyz'; for ( $i = 0; $i < strlen( $text ); $i++ ) {
    }

    $max    = strlen( $text );
    for ( $i = 0; $i < $max; $i++ ) {
    }
 
Die erste Schleife dauert fast drei mal so lang, wie die zweite. Denn für die erste Schleife muss bei jedem Schleifendurchlauf die Länge der Zeichenkette berechnet werden, für die zweite nur ein einziges Mal für die Hilfsvariable $max.

Beispiel 3.b (Sortieren eines Arrays mit Zahlwerten):
 $max = 5000; $values = array(); for ( $i = 0; $i < $max; $i++ )
        $values[]    = floor( rand( 0, 1000 ) );

    $values2    = $values;

    # Fall 1

    for ( $i = 0; $i < $max - 1; $i++ ) {
        $indexLowest    = $i;
        for ( $j = $i + 1; $j < $max; $j++ ) {
            if ( $values[$j] < $values[$indexLowest] ) {
                $indexLowest   = $j;
            }
        }
        $temp                  = $values[$i];
        $values[$i]            = $values[$indexLowest];
        $values[$indexLowest]  = $temp;
    }

    # Fall 2

    for ( $i = 0; $i < $max - 1; $i++ ) {
        $indexLowest    = $i;
        $valueLowest    = $values2[$i];
        for ( $j = $i + 1; $j < $max; $j++ ) {
            if ( $values2[$j] < $valueLowest ) {
                $indexLowest   = $j;
                $valueLowest   = $values2[$j];
            }
        }
        $temp                  = $values2[$i];
        $values2[$i]           = $values2[$indexLowest];
        $values2[$indexLowest] = $temp;
    }
 
Ein Array von 5000 zufälligen Zahlen wird sortiert, indem in zwei Schleifen jeder Wert mit jedem anderen verglichen wird und dann der niedrigste dabei gefundende Werte nach vorne in den nicht mehr zu sortierenden Bereich getauscht wird.
Obwohl in beiden Fällen dieselben Werte sortiert werden und derselbe Algorithmus verwendet wird, ist der erste Fall etwa 15% langsamer als der zweite. Dies liegt daran, daß im ersten Fall bei jedem Vergleich der aktuelle Wert aus dem Array geholt wird ($values[$indexLowest]), beim zweiten Fall jedoch nur dann, wenn der Wert sich ändert ($valueLowest = $values2[$j]). Sonst wird im zweiten Fall immer mit dem Wert der Hilfvariablen verglichen.

Diese Regeln gelten übrigens pauschal für alle Programmiersprachen.

Resümee

Wie gezeigt, kann man durch etwas Achtsamkeit durchaus merklich (zumindest aus Sicht der CPU) die Ablaufgeschwindigkeit von PHP-Scripten beeinflußen.
Dabei sollte man jedoch nie aus den Augen verlieren, daß fast immer die Verständlichkeit des produzierten Codes an erster Stelle stehen sollte. Denn Computer werden immer schneller. Der Code hingegen bleibt meist Jahre lang derselbe.




© Bodo Kälberer | Letzte Änderung: 7.0.2002 - 8: 0 | Original Fundort