php 读取目录与扫描目录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8692764/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 05:17:05  来源:igfitidea点击:

readdir vs scandir

php

提问by ThinkingMonkey

1] Which of the functions is faster?
2] what are the differences?

1] 哪个功能更快?
2]有什么区别?

Differences

Differences

1] readdir returns the name of the next entry in the directory. Scandir returns an array of files and directories from the directory.

2] readdir has to have a resource handle open until all the entries are read. scandir, perhaps creates an array of all the entries and closes the resouce handle?

1] readdir 返回目录中下一个条目的名称。Scandir 返回目录中的文件和目录数组。

2] readdir 必须打开一个资源句柄,直到所有条目都被读取。scandir,也许会创建一个包含所有条目的数组并关闭资源句柄?

采纳答案by Aufziehvogel

Just getting the results (without doing anything), readdir is a minimum faster:

只是得到结果(不做任何事情), 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";

Gives:

给出:

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

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

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

Then of course it depends on what you intend to do. If you have to write another loop with scandir(), it will be slower.

那么当然这取决于你打算做什么。如果你必须用 scandir() 编写另一个循环,它会更慢。

回答by Robert Allan Hennigan Leahy

It really depends what you're doing with the data.

这实际上取决于您对数据的处理方式。

If you're going through entry-by-entry, you should be using readdir, if you actually need to have a list of the entries in memory, you should be using scandir.

如果您要逐个条目进行操作readdir,则应该使用,如果您确实需要在内存中列出条目,则应该使用scandir.

There's no sense copying information into memory when you're going to be using it entry-by-entry anyway. Lazy evaluation is definitely the way to go in that case.

无论如何,当您要逐项使用信息时,将信息复制到内存中是没有意义的。在这种情况下,惰性求值绝对是可行的方法。

I would imagine that scandiris just a wrapper around the same thing that readdiris calling, and would therefore be slower.

我想这scandir只是对readdir调用的同一事物的包装,因此会更慢。

回答by Vitaly

I know this question may be not actual now, but to append I have done some tests (like Aufziehvogel and Sayahan) with a small difference - on a directory with 1,000,000 small (a few bytes) files.

我知道这个问题现在可能不是实际的,但为了附加我已经做了一些测试(如 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;

Results (HDD):

结果(硬盘):

scandir:           1.9403479099274
readdir:           0.79462885856628
DirectoryIterator: 0.5853099822998

Results (SSD):

结果(SSD):

scandir:           0.83593201637268
readdir:           0.35835003852844
DirectoryIterator: 0.28022909164429

CPU: AMD A10-4600M APU with Radeon(tm) HD Graphics (4 cores)
MEM: 8G
PHP: 5.6.29

CPU:AMD A10-4600M APU 带 Radeon(tm) 高清显卡(4 核)
MEM:8G
PHP:5.6.29

回答by Erik Liljencrantz

Did some more timing comparisons for reading an entire directory tree with plenty of files and directories:

对读取包含大量文件和目录的整个目录树进行了更多时间比较:

  • the call filetype()=="dir"is clearly faster than the is_dir() call

  • the opendir/readdircalls are much faster than the RecursiveDirectoryIterator

  • building the directory tree using recursive calls depth first or linear makes no difference

  • 调用filetype()=="dir"显然比 is_dir() 调用快

  • 执行opendir / readdir的电话是多少比RecursiveDirectoryIterator快

  • 使用递归调用深度优先或线性构建目录树没有区别

The above tests where performed in Windows on local SSD, local USB and network drive with consistent results. Running on the network drive was up to 180 times slower than local drives - despite gigabit and otherwise fast ReadyNAS unit!

上述测试在 Windows 本地 SSD、本地 USB 和网络驱动器上执行,结果一致。在网络驱动器上运行的速度比本地驱动器慢 180 倍——尽管有千兆和其他快速 ReadyNAS 设备!

The number of entries handled per second ranged from 115 with the slowest code to the network drive to almost 65 000 for the fastest code to the USB 3.0 drive - due to caching of course.

每秒处理的条目数从 115 条到网络驱动器的最慢代码到几乎 65 000 条到 USB 3.0 驱动器的最快代码——当然是由于缓存。

But the huge difference for the network drive makes You wonder what happens inside PHP as the simple dir command and ls in Linux over the same files is much quicker.

但是网络驱动器的巨大差异让您想知道 PHP 内部会发生什么,因为简单的 dir 命令和 Linux 中的 ls 对相同的文件要快得多。

To be continued...

未完待续...

回答by Sayahan

I have done some tests. (Thanks to Aufziehvogel for construction)

我做了一些测试。(感谢 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 Server Results:

Linux 服务器结果:

scandir: 0.82553291320801
readdir: 0.91677618026733
glob   : 0.76309990882874

This Reasults from 4 cores (8 Threads) intel E3-1240 Cpu linux + Apache server.

这是 4 核(8 线程)英特尔 E3-1240 Cpu linux + Apache 服务器的结果。

But Windows Servers results is opposite. Windows + Apache server - Intel Q8400 4 Core (4 Threads)

但 Windows Servers 结果相反。Windows + Apache 服务器 - 英特尔 Q8400 4 核(4 线程)

Windows Server Results:

Windows 服务器结果:

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

scandir: 0.61557507515
readdir: 0.614650011063
glob   : 1.92112612724

(Folder includes 13 files. If files is increase, results can be different)

(文件夹包含13个文件。如果文件增加,结果可能会有所不同)