2012-01-01 46 views
29

1] ¿Cuál de las funciones es más rápida?
2] ¿Cuáles son las diferencias?
readdir vs scandir

Differences

1] readdir devuelve el nombre de la siguiente entrada en el directorio. Scandir devuelve una matriz de archivos y directorios del directorio.

2] readdir tiene que tener un identificador de recurso abierto hasta que se lean todas las entradas. scandir, ¿tal vez crea una matriz de todas las entradas y cierra el control de recursos?

+0

posible duplicado de [Directorio a array con PHP] (http://stackoverflow.com/questions/2120287/directory-to-array-with-php) – salathe

Respuesta

12

El simple hecho de los resultados (sin hacer nada), readdir es un mínimo más rápido:

<?php 

$count = 10000; 

$dir = '/home/brati'; 

$startScan = microtime(true); 
for ($i=0;$i<$count;$i++) { 
    $array = scandir($dir); 
} 
$endScan = microtime(true); 


$startRead = microtime(true); 
for ($i=0;$i<$count;$i++) { 
    $handle = opendir($dir); 
    while (false !== ($entry = readdir($handle))) { 
     // We do not know what to do 
    } 
} 
$endRead = microtime(true); 

echo "scandir: " . ($endScan-$startScan) . "\n"; 
echo "readdir: " . ($endRead-$startRead) . "\n"; 

Da:

== RUN 1 == 
scandir: 5.3707950115204 
readdir: 5.006147146225 

== RUN 2 == 
scandir: 5.4619920253754 
readdir: 4.9940950870514 

== RUN 3 == 
scandir: 5.5265231132507 
readdir: 5.1714680194855 

Luego, por supuesto, depende de lo que pretende hacer. Si tiene que escribir otro ciclo con scandir(), será más lento.

15

Realmente depende de lo que estés haciendo con los datos.

Si está ingresando entrada por entrada, debe usar readdir, si realmente necesita tener una lista de las entradas en la memoria, debe usar scandir.

No tiene sentido copiar información en la memoria cuando va a utilizarla entrada por entrada de todos modos. La evaluación perezosa es definitivamente el camino a seguir en ese caso.

Me imagino que scandir es solo un contenedor alrededor de lo mismo que readdir está llamando, y por lo tanto sería más lento.

2

hicimos un poco más comparaciones de tiempo para la lectura de un árbol de directorios con un montón de archivos y directorios:

  • la llamada tipo de archivo() == "dir" es claramente más rápido que la llamada is_dir()

  • los opendir/rEADDIR llamadas son mucho más rápido que el edificio RecursiveDirectoryIterator

  • el árbol de directorios utilizando la profundidad llamadas recursivas primera o lineal no hace ninguna diferencia

Las pruebas anteriores, donde actuaron en Windows en SSD locales, USB local y unidad de red con resultados consistentes. La ejecución en la unidad de red fue hasta 180 veces más lenta que las unidades locales, ¡a pesar del gigabit y, por lo demás, de la unidad ReadyNAS rápida!

El número de entradas manejadas por segundo varió de 115 con el código más lento a la unidad de red a casi 65 000 para el código más rápido a la unidad USB 3.0, debido al almacenamiento en caché, por supuesto.

Pero la gran diferencia para la unidad de red hace que se pregunte qué pasa dentro de PHP, ya que el comando simple dir y ls en Linux sobre los mismos archivos es mucho más rápido.

Continuará ...

2

He hecho algunas pruebas. (Gracias a Aufziehvogel para la construcción)

$count = 100000; 

$dir = dirname(__FILE__); 

$startScan = microtime(true); 
for ($i=0;$i<$count;$i++) { 
    $array = scandir($dir); 
} 
$endScan = microtime(true); 

$startRead = microtime(true); 
for ($i=0;$i<$count;$i++) { 
    $handle = opendir($dir); 
    while (false !== ($entry = readdir($handle))) { 
     // We do not know what to do      
    } 
} 
$endRead = microtime(true); 

$startGlob = microtime(true); 
for ($i=0;$i<$count;$i++) { 
    $array3 = glob('*'); 
} 
$endGlob = microtime(true); 

echo "scandir: " . ($endScan-$startScan) . "\n"; 
echo "readdir: " . ($endRead-$startRead) . "\n"; 
echo "glob : " . ($endGlob-$startGlob) . "\n"; 

Resultados servidor Linux:

scandir: 0.82553291320801 
readdir: 0.91677618026733 
glob : 0.76309990882874 

Este Reasults de 4 núcleos (8 hilos) Intel E3-1240 Cpu Linux + servidor Apache.

Pero los resultados de Windows Servidores son lo opuesto. servidor de Windows + Apache - Intel Q8400 4 Core (4 hilos)

Server Resultados de Windows:

$count = 10000; // it was on linux 100000 :) 

scandir: 0.61557507515 
readdir: 0.614650011063 
glob : 1.92112612724 

(carpeta incluye 13 archivos Si los archivos es aumento, los resultados pueden ser diferentes.)

2

que sé esta pregunta puede no ser real ahora, pero para agregar he hecho algunas pruebas (como Aufziehvogel y Sayahan) con una pequeña diferencia: en un directorio con 1,000,000 de archivos pequeños (unos pocos bytes).

$dir = dirname(__FILE__) . '/dir'; 

$startScan = microtime(true); 
$array = scandir($dir); 
for ($i = 0, $j = count($array); $i < $j; $i++) { 
    // Code 
} 
$endScan = microtime(true); 
unset($array); 

$startRead = microtime(true); 
$handle = opendir($dir); 
while (false !== ($entry = readdir($handle))) { 
    // Code 
} 
$endRead = microtime(true); 
unset($handle); 
unset($entry); 

$startDir = microtime(true); 
$files = new DirectoryIterator($dir); 
foreach ($files as $file) { 
    // Code 
} 
$endDir = microtime(true); 
unset($files); 

echo 'scandir:   ', ($endScan - $startScan), PHP_EOL; 
echo 'readdir:   ', ($endRead - $startRead), PHP_EOL; 
echo 'DirectoryIterator: ', ($endDir - $startDir), PHP_EOL; 

Resultados (HDD):

scandir:   1.9403479099274 
readdir:   0.79462885856628 
DirectoryIterator: 0.5853099822998 

Resultados (SSD):

scandir:   0.83593201637268 
readdir:   0.35835003852844 
DirectoryIterator: 0.28022909164429 

CPU: APU A10-4600M AMD con Radeon (tm) Gráficos HD (4 núcleos)
MEM: 8G
PHP: 5.6.29

Cuestiones relacionadas