XaraX: Geschwindigkeit von for-Schleifen

Beitrag lesen

Hallo Tom,

tschuldige, das war auch etwas überfallsartig ;) eddi ist mein ShellScript, mit dem ich auf allen meinen Systemen den Aufruf von PHP-CLI erledige. D. h. PHP kann auf einem abgeschirmten System nur mit den Minimaldiensten ohne Server oder Ähnlichem seinen Dienst vollziehen. Dem Script wird als Parameter der Name eines Scriptes übergeben: eddi g-test. Das ShellScript eddi ruft damit folgendes auf:

env -i /home/eddi/bin/5.0.3/bin/php -f /home/eddi/phpscripte/g-test.php $@

Mit dem Aufruf an der Konsole eddi g-test 10000 übergebe ich noch den Parameter 10000, der Durchlaufanzahl bestimmt.

############################ g-test.php ###################################

<?php
ini_set('max_execution_time',200);
ini_set('memory_limit','50M');

$u wird Durch Prüfung Erstellt. Ist der zweite Parameter an der Konsole

eingegeben worden, so wird $u dieser zugewiesen; andernfalls "1" als

Durchlaufanzahl

$u=$argv[1] ? $argv[1] : 1;

test1.txt ist ein 1050112 Byte große Datei, die mit file() ein Daten-

feld mit Index 0-1535 erzeugt 1/3 der Strings ist 1.0 kB, 1/3 ist

0.67 kB und 1/3 ist 0.33 kB groß.

Die Datei kann zum Vergleich unter

http://eddi.to-grip.de/versuch/test1.txt heruntergeladen werden.

$a=file('test1.txt');

Der Prozess wird zum Vergleich ausgesetzt

sleep(1);

Beispiel für die Ausgabe von microtime(): "0.96838300 1105291560"

Die Ausgabe von microtime() wird ein Datenfeld umgewandelt

echo $start[0]; => "0.96838300" // (Sekundenbruchteil)

echo $start[1]; => "1105291560" // (wie 'echo time();')

$start=explode(' ',microtime());

Beim Beispiel ("0.96838300 1105291560") beleibend wäre die genaue Zeit

also 1105291560.96838300. Anders ausgedrückt sind das alle Zeichen von

$start[1] verbunden mit den letzen neune Zeichen von $start[0]:

$start=$start[1].substr($start[0],-9);

die erste Testreihe mit $u Durchläufen beginnt

for($i=0;$i<$u;$i++)
   {

wird das Datenfeld $a durchlaufen

for($j=0;$j<count($a);$j++);
   }

$end siehe $start

$end=explode(' ',microtime());
$end=$end[1].substr($end[0],-9);

Ausgabe an der Konsole:

$end - $start ergibt die exakte Dauer in Sekunden der Durchläufe $u für

for($j=0;$j<count($a);$j++); als _FOR_ mit _C_ount "for_c"

str_pad() naja ;) man ist ja Ästhet

echo 'for_c  : '.str_pad(($end-$start),16)."\n";

um das Ergebnis keinsterleiweise zu beeinflussen bekommt jede funktion

die gleichen $GLOBALS übergeben, daher wird $j und $i gelöscht

unset($j,$i);

Der Prozess wird zum Vergleich ausgesetzt und abhieran wiederholen sich

die Dinge

sleep(1);
$start=explode(' ',microtime());
$start=$start[1].substr($start[0],-9);

for($i=0;$i<$u;$i++)
 {
 foreach($a as $v);
 }

$end=explode(' ',microtime());
$end=$end[1].substr($end[0],-9);
echo 'foreach  : '.str_pad(($end-$start),16)."\n";
unset($v,$i);
sleep(1);
$start=explode(' ',microtime());
$start=$start[1].substr($start[0],-9);

for($i=0;$i<$u;$i++)
 {
 for($j=0;$a[$j];$j++);
 }

$end=explode(' ',microtime());
$end=$end[1].substr($end[0],-9);
echo 'for  : '.str_pad(($end-$start),16)."\n";

es wird die Anzahl der Duchläufe ausgegeben

echo 'Durchlaeufe : '.$u;
?>

#####################Ausgabe an der Konsole ###############################

Das ist mein Code, mit dem ich Geschwindigkeitstests durchführe. Jedoch ist anzumerken, das die Kommentare herauszunehmen sind! Aus irgendeinem Grund beinflussen diese das Ergebnis...

Die schnellste Methode von -for vs foreach- ist in diesem Test allerdings:

$b=count($a);
for($i=0;$i<$u;$i++)
   {
   for($j=0;$j<$b;$j++);
   }

Dabei wird count nicht bei jedem Aufruf folzogen, was noch mehr spart, aber
erst in Konstrukten wie

while()
   for()

oder

foreach()
   for()

im Realem seine Wirkung vollzieht.

Gruß aus Berlin!
eddi