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