Подтвердить что ты не робот

Чтение и скандир

1] Какая из функций быстрее?
2] какие отличия?

Differences

1] readdir возвращает имя следующей записи в каталоге. Scandir возвращает массив файлов и каталогов из каталога.

2] readdir должен иметь дескриптор ресурса, пока все записи не будут прочитаны. scandir, возможно, создает массив всех записей и закрывает ручку resouce?

4b9b3361

Ответ 1

Просто получая результаты (ничего не делая), readdir работает быстрее:

<?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";

дает:

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

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

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

Тогда, конечно, это зависит от того, что вы намереваетесь сделать. Если вам нужно написать еще один цикл с помощью scandir(), он будет медленнее.

Ответ 2

На самом деле это зависит от того, что вы делаете с данными.

Если вы переходите через запись, вы должны использовать readdir, если вам действительно нужен список записей в памяти, вы должны использовать scandir.

В любом случае нет смысла копировать информацию в память, когда вы собираетесь использовать ее по очереди. Ленькая оценка - это, безусловно, способ пойти в этом случае.

Я бы предположил, что scandir является всего лишь оберткой вокруг того же самого, что readdir вызывает, и поэтому будет медленнее.

Ответ 3

Сделал еще несколько сравнений времени для чтения всего дерева каталогов с большим количеством файлов и каталогов:

  • вызов filetype() == "dir" явно быстрее, чем вызов is_dir()

  • вызовы opendir/readdir намного быстрее, чем RecursiveDirectoryIterator

  • построение дерева каталогов с использованием рекурсивных вызовов глубины первого или линейного значения не имеет значения

Вышеприведенные тесты, которые выполняются в Windows на локальном SSD, локальном USB и сетевом диске с постоянными результатами. Запуск на сетевом диске был в 180 раз медленнее, чем локальные диски - несмотря на гигабитный и быстрая система ReadyNAS!

Количество записей, обрабатываемых в секунду, варьировалось от 115 с самым медленным кодом до сетевого диска почти до 65 000 для самого быстрого кода на накопителе USB 3.0 - из-за кэширования, конечно.

Но огромная разница для сетевого диска заставляет вас задаться вопросом, что происходит внутри PHP, поскольку простая команда dir и ls в Linux по тем же файлам намного быстрее.

Продолжение следует...

Ответ 4

Я сделал несколько тестов. (Благодаря Aufziehvogel для строительства)

$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";

Результаты сервера Linux:

scandir: 0.82553291320801
readdir: 0.91677618026733
glob   : 0.76309990882874

Это результаты с 4 ядер (8 потоков) Intel E3-1240 Cpu linux + сервер Apache.

Но результаты Windows Servers противоположны. Сервер Windows + Apache - Intel Q8400 4 Core (4 потока)

Результаты Windows Server:

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

scandir: 0.61557507515
readdir: 0.614650011063
glob   : 1.92112612724

(Папка содержит 13 файлов. Если файлы увеличиваются, результаты могут быть разными)

Ответ 5

Я знаю, что этот вопрос может быть не актуальным сейчас, но добавить. Я сделал несколько тестов (например, Aufziehvogel и Sayahan) с небольшой разницей - в каталоге с 1 000 000 маленьких (несколько байтов) файлов.

$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;

Результаты (HDD):

scandir:           1.9403479099274
readdir:           0.79462885856628
DirectoryIterator: 0.5853099822998

Результаты (SSD):

scandir:           0.83593201637268
readdir:           0.35835003852844
DirectoryIterator: 0.28022909164429

Процессор: AMD A10-4600M APU с графикой Radeon (tm) HD (4 ядра)
MEM: 8G
PHP: 5.6.29