哪个更快:glob() 或 opendir()

问题描述 投票:0回答:6

对于读取 1-2K 左右的文件,

glob()
opendir()
哪个更快?

php file-io glob opendir
6个回答
11
投票

http://code2design.com/forums/glob_vs_opendir

显然

opendir()
应该(并且确实)更快,因为它打开目录处理程序并允许您进行迭代。因为
glob()
必须解析第一个参数,所以需要更多时间(加上
glob
处理递归目录,因此它会扫描子目录,这会增加执行时间。


9
投票

glob
opendir
做不同的事情。
glob
查找与模式匹配的路径名并将其返回到数组中,而
opendir
仅返回目录句柄。为了获得与
glob
相同的结果,您必须调用其他函数,在基准测试时必须考虑这些函数,特别是如果这包括模式匹配。

Bill Karwin 最近写了一篇关于此的文章。参见:


2
投票

不确定这是否是完美的比较,但

glob()
允许您合并类似 shell 的模式,以及
opendir
直接用于目录,从而使其更快。


2
投票

哪一个更快:

  • 如果你想要完整的文件名+路径,排序,glob实际上是无与伦比的。
  • 如果您想要完整的文件名+路径未排序,请使用带有 GLOB_NOSORT 的 glob。
  • 如果您只想要名称,而不需要排序,请使用 opendir + 循环。

这是一个 TLDR。
如果你赶时间,请跳过无聊的部分:)

无聊的部分

在做出选择之前,先退后一步来了解一下。您可以进行测试以使用不同的方法得出完全相同的结果,却发现它们的时间成本大致相同。仅仅为了获取信息,你不会有真正的赢家。

  1. 处理巨大的文件列表,glob 的排序速度更快 - 它使用文件系统的排序方法,这总是更优越。 (它知道它排序的内容,而 PHP 不知道,PHP 对任意字符串的散列数组进行排序,比较它们根本不公平。)

  2. 您可能希望通过某些扩展名或文件名掩码来过滤列表,而 glob 对于这些扩展名或文件名掩码确实非常有效。当然,您有 fnmatch(),但每次调用它永远不会比为此工作训练的系统级过滤器更快。

  3. 另一方面,glob返回大量文本(每个名称都有完整路径),因此对于大量文件,您可能会遇到内存分配限制。对于无数的文件,glob 不是你的朋友。


1
投票

另一个可以通过一些测试来回答的问题。我有一个方便的文件夹,里面有 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

1
投票

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>&emsp; <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
© www.soinside.com 2019 - 2024. All rights reserved.