Zählschleife so oft durchführen, wie ein Array Einträge hat

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&lt;$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!!!

Jan hat 152 Beiträge geschrieben

6 Kommentare zu “Zählschleife so oft durchführen, wie ein Array Einträge hat

  1. Tim sagt:

    Könntest du vielleicht auch noch while() und next()/current()/key()/value() untersuchen?

    Danke!

    Gruß
    Tim

  2. Benni sagt:

    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.

  3. workerholic sagt:

    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…!

  4. Jan sagt:

    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.

  5. workerholic sagt:

    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

  6. Jan sagt:

    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.

Eine Antwort schreiben

Ihre E-Mail-Adresse wird nicht veröffentlicht. Benötigte Felder sind markiert mit *

You may use these HTML tags and attributes: <a href=""> <blockquote cite=""> <pre lang=""> <b> <strong> <i> <em>