Schleifen, die ein Array durchlaufen sind sehr häufig. Dazu gibt es entweder die foreach-Schleife oder die for-Schleife mit Zählvariable. Besonders bei letzterer sieht man sowohl in von Hobbyprogrammiern als auch in von professionellen Entwicklern programmiertem Code recht häufig folgenden Schleifenkopf:
$array = array(...); for($i=0;$i<count($array);$i++)> ... } |
Das count muss dabei allerdings bei jedem Schleifendurchlauf wieder berechnet werden, damit die Bedingung überprüft werden kann (ob $i<count($array)). Das ist unnötig.
Performanter geht es mittels folgender Funktion:
$array = array(...); $cnt_array = count($array); for($i=0;$i<$cnt_array;$i++) { ... } |
Etwa gleichwertig zum Bestimmen der Array-Länge vor der Schleife ist die Funktion foreach:
foreach($array as $item) { ... } |
Auswertung:
Die konstanten Variante (Arraylänge vor der Schleife bestimmt) und die foreach-Variante benötigen pro Durchlauf durchschnittlich ca 9 ms und die dynamische (Länge im Schleifenkopf bestimmt) knapp 14 ms. Die konstante Version ist also über 50 % schneller als die dynamische!!!
Datei | Gesamtlaufzeit | durchschnittliche Laufzeit pro Durchlauf | Verhältnis zur schnellsten Variante |
---|---|---|---|
loop_constant.php | 9,12 s | 9,123 ms | 100% |
loop_foreach.php | 9,17 s | 9,173 ms | 101% (+ 1%) |
loop_dynamic.php | 13,80 s | 13,800 ms | 151% (+ 51%) |
Wer es selbst nachprüfen möchte: Quellcodes für das Durchlaufen eines Arrays.
Und als Beweis natürlich auch die Benchmark-Ergebnisse
Merke: Konstanten (bzw. Werte, die innerhalb der Schleife nicht verändert werden) nicht in jedem Schleifendurchlauf neu berechnen lassen!!!
Könntest du vielleicht auch noch while() und next()/current()/key()/value() untersuchen?
Danke!
Gruß
Tim
Irgendwie war mir das von Anfang an klar, dass es schneller sein muss, wenn die Schleife nur noch auf einen bereits ausgerechneten Wert zugreifen muss, anstatt diesen jedes Mal neu zu berechnen.
Aber dass das so viel schneller ist hätte ich nicht gedacht. Ebensowenig wie damit, dass eine foreach-Schleife nahezu gleich schnell ist.
Also was mich Interessieren würde, warum die Version schneller ist, wo man den count außerhalb der schleife hat und warum dann doch foreach dann doch ein tick langsamer ist?! immerhin muss der doch für die variable i doch speicher bereitstellen und die variable muss auch immer geändert werden, was auch zeit kostet…!
Ganz einfach: weil sonst bei jedem Schleifendurchlauf dieFunktion count() auf das Array ausgeführt werden muss. Und bei der Variante außerhalb eben nur einmal und anschließend nur ein Konstantenvergleich pro Schleifendurchlauf.
ja ging aber jetzt mit dem vergleich von foreach… nicht mit der anderen for 😉 in der foreach muss ja nicht noch extra eine variable mitgeschleppt werden! aber in der for schon, wie kann es dann schneller sein?! da muss bei der implementierung schiefgelaufen sein :p
Die foreach hat ein anderes Problem: Sie muss ständig das jeweils aktuelle Arrayelement auf die temporäre Variable umspeichern. Ansonsten ist sie baugleich mit der for-Schleife, wenn man vorher die Anzahl bestimmt.