9

PHP でGnu Find ("find .")を複製しようとしてきましたが、その速度に近づくことさえ不可能のようです。PHP 実装は、Find の少なくとも 2 倍の時間を使用します。PHPでこれを行うより速い方法はありますか?

編集: SPL 実装を使用したコード例を追加しました -- そのパフォーマンスは反復アプローチと同等です

EDIT2: PHP から find を呼び出すと、実際にはネイティブ PHP 実装よりも遅くなりました。私は自分が持っているものに満足すべきだと思います:)

// measured to 317% of gnu find's speed when run directly from a shell
function list_recursive($dir) { 
  if ($dh = opendir($dir)) {
    while (false !== ($entry = readdir($dh))) {
      if ($entry == '.' || $entry == '..') continue;

      $path = "$dir/$entry";
      echo "$path\n";
      if (is_dir($path)) list_recursive($path);       
    }
    closedir($d);
  }
}

// measured to 315% of gnu find's speed when run directly from a shell
function list_iterative($from) {
  $dirs = array($from);  
  while (NULL !== ($dir = array_pop($dirs))) {  
    if ($dh = opendir($dir)) {    
      while (false !== ($entry = readdir($dh))) {      
        if ($entry == '.' || $entry == '..') continue;        

        $path = "$dir/$entry";        
        echo "$path\n";        
        if (is_dir($path)) $dirs[] = $path;        
      }      
      closedir($dh);      
    }    
  }  
}

// measured to 315% of gnu find's speed when run directly from a shell
function list_recursivedirectoryiterator($path) {
  $it = new RecursiveDirectoryIterator($path);
  foreach ($it as $file) {
    if ($file->isDot()) continue;

    echo $file->getPathname();
  }
}

// measured to 390% of gnu find's speed when run directly from a shell
function list_gnufind($dir) { 
  $dir = escapeshellcmd($dir);
  $h = popen("/usr/bin/find $dir", "r");
  while ('' != ($s = fread($h, 2048))) {
    echo $s;
  }
  pclose($h);
}
4

7 に答える 7

3

PHP は、単純明快な C ほど速く実行することはできません。

于 2009-03-08T20:17:44.647 に答える
0

scandir()Jason Cohenが提案したように、を使用してディレクトリ全体を一度に読み取ってみてください。私は次のコードをphpマニュアルのコメントからのコードに基づいていますscandir()

 function scan( $dir ){
        $dirs = array_diff( scandir( $dir ), Array( ".", ".." ));
        $dir_array = Array();
        foreach( $dirs as $d )
            $dir_array[ $d ] = is_dir($dir."/".$d) ? scan( $dir."/".$d) : print $dir."/".$d."\n";
 }
于 2009-10-28T15:33:04.767 に答える