Ich habe getestet:
Testbedingungen
- PHP-Version: 4.3.4
- Apache-Version: 2.0.48
- Betriebssystem: Windows 2000 SP 4
- Dateisystem: FAT32
- Prozessor: AMD Athlon XP 2500+
- Hauptspeicher: 512 MB
- Verwendeter Browser: Firefox 0.9 Englisch
- Eingelesene Ordner und Unterordner: 4010
- Anzahl Dateien in diesen Ordnern: 70.976
- Dateigröße (insgesamt):4.146.029.914 bytes
- Der Webserver befindet sich auf dem Arbeitsrechner, wurde also als localhost angesprochen.
Bedingungen an die Ausgabe
- Ausgabe als unsortierte verschachtelte Liste
- Nur Ordner, keine Dateien ausgeben
- Innerhalb eines Ordners sollen Unterordner nach Namen sortiert werden.
- Ausgabe eines Listenelements soll nur den eigenen Ordnernamen enthalten
Die Skripte
Testskript für readdir():
PHP:
<html>
<head>
</head>
<body>
<?php
$sTime = explode(" " , microtime());
$sTime = $sTime[1] + $sTime[0];
function rDir($dir, $ind="") {
$handle=openDir($dir);
$dirContent=array();
while ($dirContent[]=readdir($handle)){}
closedir($handle);
if (sizeof($dirContent)>2) {
sort($dirContent);
$ulPut=false;
foreach($dirContent as $d) {
if (!empty($d)
&& $d!="."
&& $d!=".."
&& is_dir($dir.$d)) {
if (!$ulPut) {
echo $ind."<ul>\n";
$ulPut=true;
}
echo $ind." <li>\n";
echo $ind." ".$d."\n";
rDir($dir.$d."/",$ind." ");
echo $ind." </li>\n";
}
}
if ($ulPut) {
echo $ind."</ul>\n";
}
}
}
rDir('./content/');
$eTime = explode(" " , microtime());
$eTime = $eTime[1] + $eTime[0];
$time = $eTime - $sTime;
$time = round($time, 3);
echo str_replace(".",",",$time)." sec";
?>
</body>
</html>
Testskript für glob():
PHP:
<html>
<head>
</head>
<body>
<?php
$sTime = explode(" " , microtime());
$sTime = $sTime[1] + $sTime[0];
function rDir($dir, $ind="") {
$dirContent=glob($dir."*",GLOB_ONLYDIR);
if (sizeof($dirContent)>0) {
echo $ind."<ul>\n";
foreach($dirContent as $d) {
echo $ind." <li>\n";
echo $ind
." "
.preg_replace("/((.*?)\/)*(.*?)$/","\\3",$d)
."\n";
rDir($d."/",$ind." ");
echo $ind." </li>\n";
}
echo $ind."</ul>\n";
}
}
rDir('./content/');
$eTime = explode(" " , microtime());
$eTime = $eTime[1] + $eTime[0];
$time = $eTime - $sTime;
$time = round($time, 3);
echo str_replace(".",",",$time)." sec";
?>
</body>
</html>
Stichprobe
Jedes der Skripte wurde 20 mal getestet. Die ersten 10 mal je Skript wurden die Skripte abwechselnd aufgerufen, die letzten 10 Male jedes Skript 10 mal hintereinander.
Vorbemerkungen
Die Verwendung von glob() ohne das Flag GLOB_ONLYDIR mit anschließender Reduktion auf Ordner wurde nach dem fünften Versuch verworfen, da es in allen fünf Versuchen mehr als zwei Sekunden länger brauchte, als das jetzt verwendete Skript für glob().
Das Weglassen des in dem glob()-Skript verwendeten regulären Ausdruck zum reduzieren auf den eigentlichen Ordnernamen des Ordners hat in weiteren Tests keine erkennbaren Verbesserungen gebracht.
Beide Skripte erzeugen die gleiche Ausgabe.
Ergebnis
Kurz und knapp: Unter den gegebenen Bedingungen mit diesen Skripten ist readdir() schneller.
Das glob()-Skript benötigte im arithmetischen Mittel 12,7023 Sekunden bei einer Varianz von 0,017337168 sek².
Das readdir()-Skript benötigte im arithmetischen Mittel 11,3469 Sekunden bei einer Varianz von 0,021344726 sek².
Der langsamste Durchlauf von readdir() war schneller, als der schnellste Durchlauf von glob().
Alle Zeiten von glob() (in Sekunden):
- 12,541
- 12,750
- 12,711
- 12,892
- 12,886
- 12,855
- 12,642
- 12,528
- 12,639
- 12,675
- 12,770
- 13,003
- 12,608
- 12,630
- 12,553
- 12,548
- 12,638
- 12,736
- 12,657
- 12,784
Alle Zeiten von readdir():
- 11,415
- 11,386
- 11,199
- 11,441
- 11,475
- 11,660
- 11,196
- 11,214
- 11,262
- 11,173
- 11,216
- 11,455
- 11,610
- 11,332
- 11,270
- 11,508
- 11,368
- 11,274
- 11,146
- 11,338
Nachbemerkung
Dieser Test bildet nur eine sehr spezifische Testumgebung ab. Er veranlasst mich weiterhin readdir() zu verwenden.
Jeder kann mit diesen Skripten gerne unter anderen Umgebungen testen und seine Ergebnisse hier (bitte mit Angabe der Umgebungsbedingungen) präsentieren.
Interessant sind sicher andere Dateisysteme (NTFS und insbesondere Linuxdateisysteme) und ein Test unter PHP5 mit scandir(). Vielleicht führen ja auch andere Dimensionen der Ordnerstruktur zu umgekehrten Ergebnissen.
Die Skripte sind evtl. auch noch verbesserungsfähig (in Bezug auf die Geschwindigkeit).
Außerdem mag das Einbeziehen von Dateien andere Ergebnisse hervorrufen.
Soviel zu meinem Test.
Gruß hpvw
PS: @Sicaine Da mein eigentlicher Server, der am Netz hängt, mit der unglaublichen Power von 350 Mhz bestückt ist, sind diese Operationen für mich auf jeden Fall zeitkritisch, auch bereits bei kleineren Dimensionen.