KingCrunchs kleine Welt

Gedanken über PHP und was mich sonst bewegt…

Gegen Mikrooptimierung: Zwei Schleifen sind schlecht?

| 6 Kommentare

PHP5.4 ist kurz vor der Beta, dass heißt die große Zeit der Neuvorstellungen ist erstmal vorbei, und solange ich nun darüber nachdenke, welchem Thema ich mir als Nächstes annehme, habe ich heute etwas Blog-Tuning betrieben. Das unsägliche Javascript der diversen Social-Bla sind statischen Links gewichen (und sowas). Statt 400kB sind es jetzt nur noch 250kB ohne und 25kB mit Cache.

Als kleine Brücke bis zum nächsten interessanten (?) Beitrag und damit Besucher ein Grund haben den ungeahnten Speed (und die Werbung *hust* :X) zu genießen, gibt es jetzt nur ein kleines Rätsel: Welches von Beiden ist schneller?

for ($i = 0; $i < = 1000000; $i++) {
    $array[$i] = $array[$i] * $array[$i];
    $array[$i] = base_convert($array[$i], 10, 16);
}
for ($i = 0; $i < 1000000; $i++) {
    $array[$i] = $array[$i] * $array[$i];
}
for ($i = 0; $i < 1000000; $i++) {
    $array[$i] = base_convert($array[$i], 10, 16);
}

Das ist etwas, was ich mir selbst immer wieder ins Gedächtnis rufen muss, denn die Antwort lautet: Keins von Beiden ist schneller. Die Details spare ich mir — wenn sie jemanden interessieren, kann ich sie nachreichen –, aber Fakt ist, dass beide Code-Schnippsel aus 2 Operationen/Funktionen bestehen, die jeweils 1000000 aufgerufen werden, und dagegen sind die Schleifen vollständig vernachlässigbar.

Aber warum ist das wichtig? Wichtig ist es in dem Sinne nicht, aber man hat nun kein Grund mehr Schleifen zu überladen, denn mit diesem Wissen kann man ohne schlechtem Gewissen mehrere Operationen auf den selben Datensatz auf mehrere Schleifen verteilen. Das gilt besonders dann, wenn man sich durch den Drang alles in eine Schleife zu komprimieren einiger nützlicher Techniken verwehrt.

$time = microtime(true);
$array = array_map(function ($item) {
    return base_convert(sqrt($item), 10, 16);
}, $array);
$time = microtime(true);
$array = array_map(function ($item) {
    return base_convert($item, 10, 16);
}, array_map('sqrt', $array));

Hier war bei mir die erste Variante tatsächlich rekonstruierbar geringfügig langsamer (nicht repräsentativ), obwohl die zweite Variante zwei Schleifen enthält (array_map() iteriert auch ;) ). DIe Analyse, warum das so ist, habe ich mir gespart (ich weiß es also nicht). Es soll jetzt nur zeigen, dass gerade mit array_map() (und Konsorten) schöner und lesbarer Code möglich ist.

6 Kommentare

  1. Hm, also die for-Konstruktion ist mE leichter zu lesen. Aber array_map ist natürlich viel cooler und man kann auch mal noch eben mit Callbacks arbeiten ;)

    • Denke, das ist auch etwas eine Sache der Gewöhnung: `array_map()` ist eher der funktionale Ansatz und der ist erst mit Closures “benutzbar” in PHP vertreten. Dann macht Formatierung noch viel aus, die `for`-Schleife ist _wirklich_ simpel undundund. Ich habe mich sowieso etwas schwer getan ein Beispiel zu finden, dass nicht ganz an den Haaren herbei gezogen ist ;) Man möge mir das nachsehen.

      Zum Thema Formatierung vielleicht noch (Ich hoffe, WordPress ruiniert es nicht direkt wieder):

      | $result = each ($values, function ($value) {
      | return floor($value / 2);
      | });

      Schon die Parameterreihenfolge bei `array_map()` finde ich etwas ungelungen. `each()` gibt es nicht, es dient aber auch nur zu Illustration ;)

  2. for ($i = 0; $i < $c; $i++) {
    Was ist denn $c ?

  3. spart mit wohl in Zukunft jede menge for schleifen :)

    • Muss zugeben, dass ich sowieso kaum `for` verwende, weil .. naja, wozu? ;) (Ich sag ma) 85% deckt bei mir `foreach` und `while` ab. Aber solange die funktionalen `array_*()`-Funktionen keine Iteratoren akzeptieren, wird man nicht komplett an irgendwas davon vorbei kommen ;)

Hinterlasse eine Antwort

Pflichtfelder sind mit * markiert.

*


Bad Behavior has blocked 239 access attempts in the last 7 days.

Page optimized by WP Minify WordPress Plugin