Multi: for vs. foreach

Mahlzeit,

bei einfachen Zählern nutze ich ab und zu die Methode

foreach(range(0,5) as $i)

in Anlehnung an Perl for (0..5)

PHP-Mäsiger ist ja immer noch

for($i = 0; $i <= 5; $i++)

Im Benchmark sind die Laufzeitunterschiede vernachlässigbar.
Jetztz würde mich mal eure Meinung zu den beiden Methoden interessieren. Was haltet ihr für besser, einfacher, "schöner", zweckmässiger usw.?

  1. Hi,

    Im Benchmark sind die Laufzeitunterschiede vernachlässigbar.
    Jetztz würde mich mal eure Meinung zu den beiden Methoden interessieren. Was haltet ihr für besser, einfacher, "schöner", zweckmässiger usw.?

    deine Methode gefällt mir besser, habs bisher klassisch gemacht.
    Hätte man auch selbst drauf kommen können ;-)

    Mike

  2. Mahlzeit!

    for($i = 0; $i <= 5; $i++)

    Diese Version ist nicht etwa PHP-mäßiger, sondern vielmehr an C(++/#)/Java(Script) und weiteren baugleichen Dialekten orientiert.

    Aufgrund dieser Übereinstimmung mit mehreren Sprachen halte ich diese Version zweckmäßiger, weil mehr Entwickler unterschiedlicher Sprachen sofort erkennen, welches Ergebnis erziehlt wird. Außerdem läßt sich der Code leichter in andere Sprachen übertragen.

    Gruß, LX

    --
    X-Self-Code: sh:( fo:) ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: Unusual
    X-Please-Search-Archive-First: Absolutely Yes
    1. Moin!

      for($i = 0; $i <= 5; $i++)

      Diese Version ist nicht etwa PHP-mäßiger, sondern vielmehr an C(++/#)/Java(Script) und weiteren baugleichen Dialekten orientiert.

      Aufgrund dieser Übereinstimmung mit mehreren Sprachen halte ich diese Version zweckmäßiger, weil mehr Entwickler unterschiedlicher Sprachen sofort erkennen, welches Ergebnis erziehlt wird. Außerdem läßt sich der Code leichter in andere Sprachen übertragen.

      Insbesondere signalisiert einem alles in dieser Zeile "Zählschleife", während das foreach-Konstrukt normalerweise nur beim Zugriff auf Arrays zum Einsatz kommt, einen also gedanklich später mal auf die völlig falsche Spur führen wird: Wo ist denn hier das Array geblieben?

      - Sven Rautenberg

      --
      "Love your nation - respect the others."
  3. Hallo,

    bei einfachen Zählern nutze ich ab und zu die Methode

    foreach(range(0,5) as $i)

    Bei kleinen Zahlen ist das egal, aber bei großen Zahlen wird das problematisch, weil Du damit ein riesiges Array anlegst, was ewig viel Speicher frisst; das gleiche Problem hast Du auch in Python, wenn Du »for i in range(...)« machst. In Python gibt's xrange() als Iterator-basierte Implementierung, die den Speicher schont. In PHP kannst Du Dir eine Iterator-basierte Implementierung selbst basteln:

    <?php  
    class XRange implements Iterator {  
      private $min;  
      private $max;  
      private $current;  
      private $counter;  
      private $step;  
      
      public function __construct ($min, $max, $step = 1) {  
        $this->min = (int)$min;  
        $this->max = (int)$max;  
        $this->step = (int)$step;  
        $this->current = $this->min;  
        $this->counter = 0;  
      }  
      
      public function rewind () {  
        $this->current = $this->min;  
        $this->counter = 0;  
      }  
      
      public function current () {  
        return $this->current;  
      }  
      
      public function key () {  
        return $this->counter;  
      }  
      
      public function next () {  
        $this->current += $this->step;  
        return $this->valid ();  
      }  
      
      public function valid () {  
        return ($this->step > 0 && $this->current <= $this->max  
          || $this->step < 0 && $this->current >= $this->max);  
      }  
    }  
      
    function xrange ($min, $max, $step = 1) {  
      return new XRange ($min, $max, $step);  
    }  
    ?>
    

    Dann kannst Du bspw. auch sowas machen wie:

    foreach (xrange (0, 1000000) as $i) {  
      if ($i % 100000 == 0) echo "$i\n";  
    }
    

    Ohne, dass Dir das Ding gleich Megabyteweise den Speicher wegfrisst. Dafür ist es *deutlich* langsamer. Mal ein paar Vergleiche:

    Code 1:
    -------

    foreach (xrange (0, 1000000) as $i) {  
      if ($i % 100000 == 0) echo "$i\n";  
    }
    

    Code 2:
    -------

    foreach (range (0, 1000000) as $i) {  
      if ($i % 100000 == 0) echo "$i\n";  
    }
    

    Code 3:
    -------

    for ($i = 0; $i <= 1000000; $i++) {  
      if ($i % 100000 == 0) echo "$i\n";  
    }
    

    Variante    | Ausführzeit (s)    | Peak-Memory-Usage (Bytes)
    ------------+--------------------+----------------------------
    1 (xrange)  | 17.38              | 93560
    2 (range)   |  1.30              | 104291308 (fast 100 MiB!)
    3 (for)     |  0.88              | 93176

    Interessant wäre höchstens noch, wie sehr die Ausführzeit zurückginge, wenn man xrange() direkt als C-Erweiterung implementiert. Mache ich nachher vielleicht noch, dann liefere ich das Ergebnis noch nach.

    Viele Grüße,
    Christian

  4. bei einfachen Zählern nutze ich ab und zu die Methode

    foreach(range(0,5) as $i)

    in Anlehnung an Perl for (0..5)

    Ich kommentiere Perl5:
    Es wird ein Array erzeugt, bevor die Schleife das erste mal abgearbeitet wird.
    Deshalb ist for(1 .. 100000){}
    ungesund.

    Perl6
    Der Array wird nur auf Bedarf erzeugt:
    for( 1 .. inf )
    lies: inf = infinity

    Klamauk
    Perl7 kennt dann forever{}

    Daraus Resultiert auch in PHP
    Eine Vorinitialisierung lohnt sich nur dann, wenn du auch alle Schleifen brauchst.

    PHP-mässiger ist ja immer noch

    for($i = 0; $i <= 5; $i++)

    Was immer die sparsamere Version ist.

    Im Benchmark sind die Laufzeitunterschiede vernachlässigbar.

    Methodisch gehört immer auch das Thema Speicher dazu.

    Jetztz würde mich mal eure Meinung zu den beiden Methoden interessieren. Was haltet ihr für besser, einfacher, "schöner", zweckmässiger usw.?

    GRINS: forever{ ;)

    mfg Beat

    --
    Woran ich arbeite:
    X-Torah
    ><o(((°>           ><o(((°>
       <°)))o><                     ><o(((°>o