glob()
对于读取大约 1-2K 的文件,在和之间哪个更快opendir()
?
6 回答
http://code2design.com/forums/glob_vs_opendir
显然opendir()
应该(并且)更快,因为它打开目录处理程序并让您进行迭代。因为glob()
必须解析第一个参数,所以需要更多时间(加上glob
处理递归目录,所以它会扫描子目录,这将增加执行时间。
glob
并opendir
做不同的事情。glob
查找与模式匹配的路径名并在数组中返回它们,同时opendir
仅返回目录句柄。要获得与您相同的结果,glob
您必须调用其他函数,在进行基准测试时必须考虑到这些函数,尤其是当这包括模式匹配时。
Bill Karwin最近写了一篇关于这个的文章。看:
不确定这是否是完美的比较,但glob()
允许您将类似 shell 的模式以及opendir
直接用于目录的位置合并到那里,从而使其更快。
另一个可以通过一些测试来回答的问题。我有一个方便的文件夹,里面有 412 个东西,但结果应该不会有太大差异,我想:
igor47@whisker ~/test $ ls /media/music | wc -l
412
igor47@whisker ~/test $ time php opendir.php
414 files total
real 0m0.023s
user 0m0.000s
sys 0m0.020s
igor47@whisker ~/test $ time php glob.php
411 files total
real 0m0.023s
user 0m0.010s
sys 0m0.010s
好的,
长话短说:
- 如果您想要完整的文件名+路径,sorted, glob 实际上是无与伦比的。
- 如果您想要完整的文件名+路径未排序,请使用带有 GLOB_NOSORT 的 glob。
- 如果您只想要名称而不需要排序,请使用 opendir + loop。
就是这样。
还有一些想法:
您可以进行测试以使用不同的方法组成完全相同的结果,结果却发现它们的时间成本大致相同。仅仅为了获取信息,您将没有真正的赢家。但是,请考虑这些:
处理一个巨大的文件列表,glob 会更快地排序——它使用文件系统的排序方法,这种方法总是更好的。(它知道它的排序,而 PHP 不知道,PHP 对任意字符串的散列数组进行排序,比较它们是不公平的。)
您可能希望通过 glob 真正有效的一些扩展名或文件名掩码来过滤您的列表。你当然有fnmatch(),但每次调用它永远不会比为这项工作训练的系统级过滤器更快。
另一方面,glob返回大量的文本(每个名称都有完整路径),因此对于大量文件,您可能会遇到内存分配限制。对于无数个文件,glob 不是你的朋友。
OpenDir 更快...
<?php
$path = "/var/Upload/gallery/TEST/";
$filenm = "IMG20200706075415";
function microtime_float()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
echo "<br> <i>T1:</i>".$t1 = microtime_float();
echo "<br><br> <b><i>Glob :</i></b>";
foreach( glob($path.$filenm.".*") as $file )
{
echo "<br>".$file;
}
echo "<br> <i>T2:</i> ".$t2 = microtime_float();
echo "<br><br> <b><i>OpenDir :</b></i>";
function resolve($name)
{
// reads informations over the path
$info = pathinfo($name);
if (!empty($info['extension']))
{
// if the file already contains an extension returns it
return $name;
}
$filename = $info['filename'];
$len = strlen($filename);
// open the folder
$dh = opendir($info['dirname']);
if (!$dh)
{
return false;
}
// scan each file in the folder
while (($file = readdir($dh)) !== false)
{
if (strncmp($file, $filename, $len) === 0)
{
if (strlen($name) > $len)
{
// if name contains a directory part
$name = substr($name, 0, strlen($name) - $len) . $file;
}
else
{
// if the name is at the path root
$name = $file;
}
closedir($dh);
return $name;
}
}
// file not found
closedir($dh);
return false;
}
$file = resolve($path.$filenm);
echo "<br>".$file;
echo "<br> <i>T3:</i> ".$t3 = microtime_float();
echo "<br><br>  <b>glob time:</b> ". $gt= ($t2 - $t1) ."<br><b>opendir time:</b>". $ot = ($t3 - $t2) ;
echo "<u>". (( $ot < $gt ) ? "<br><br>OpenDir is ".($gt-$ot)." more Faster" : "<br><br>Glob is ".($ot-$gt)." moreFaster ") . "</u>";
?>
输出:
T1:1620133029.7558
Glob :
/var/Upload/gallery/TEST/IMG20200706075415.jpg
T2: 1620133029.7929
OpenDir :
/var/Upload/gallery/TEST/IMG20200706075415.jpg
T3: 1620133029.793
glob time:0.037137985229492
opendir time:5.9843063354492E-5
OpenDir is 0.037078142166138 more Faster