【问题标题】:Which is faster: glob() or opendir()哪个更快: glob() 或 opendir()
【发布时间】:2011-02-15 08:06:27
【问题描述】:

对于读取大约 1-2K 的文件,glob()opendir() 之间哪个更快?

【问题讨论】:

  • 它们没有可比性,您应该将 glob() 与做同样事情的替代品进行比较。

标签: php file-io glob opendir


【解决方案1】:

http://code2design.com/forums/glob_vs_opendir

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      不确定这是否是完美的比较,但 glob() 允许您合并类似 shell 的模式,以及 opendir 直接用于那里的目录,使其更快。

      【讨论】:

      • glob() 使用类似 shell 的模式,而不是正则表达式
      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        好的,

        长话短说:

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

        就是这样。

        更多想法:

        您可以进行测试以使用不同的方法组合出完全相同的结果,结果却发现它们的时间成本大致相同。仅仅为了获取信息,您将没有真正的赢家。但是,请考虑以下几点:

        1. 处理一个巨大的文件列表,glob 会更快地排序 - 它使用文件系统的排序方法,这种方法总是更好的。 (它知道它的排序而 PHP 不知道,PHP 对任意字符串的散列数组进行排序,比较它们是不公平的。)

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

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

        【讨论】:

          【解决方案6】:

          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
          

          【讨论】:

            猜你喜欢
            • 2011-12-09
            • 2010-11-10
            • 2012-10-03
            • 2012-07-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-04-05
            相关资源
            最近更新 更多