2012-01-01 17 views
29

1どちらの機能が高速ですか?
2]違いは何ですか?ディレクトリ内の次のエントリの名前を返すREADDIR
readdir vs scandir

Differences

1]。 Scandirはディレクトリからファイルとディレクトリの配列を返します。

2] readdirには、すべてのエントリが読み取られるまでリソースハンドルがオープンされている必要があります。 scandir、おそらくすべてのエントリの配列を作成し、resouceハンドルを閉じますか?

+0

可能な複製[PHPを使った配列へのディレクトリ](http://stackoverflow.com/questions/2120287/directory-to-array-with-php) – salathe

答えて

12

だけ(何もせずに)結果を得る、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"; 

を与える:

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

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

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

を次に、もちろん、それはあなたがするつもりかに依存します。 scandir()で別のループを記述しなければならない場合は、遅くなります。

15

本当にあなたがデータで何をしているかによって異なります。

エントリーバイステップを通過する場合は、readdirを使用する必要があります。実際には、メモリ内のエントリのリストが必要な場合は、scandirを使用する必要があります。

とにかくエントリー単位で情報を使用しようとするときに、情報をメモリにコピーすることは意味がありません。そのような場合、遅延評価が間違いなく行われます。

scandirは、readdirが呼び出しているものと同じものを囲むラッパーに過ぎず、ゆっくりとしていると思います。

2

は、ファイルやディレクトリをたっぷり使ってディレクトリツリー全体を読み取るためのいくつかのより多くのタイミングの比較をしました:

  • を呼び出しファイルタイプ()==「DIR」が速くis_dir()の呼び出しよりも明らかです

  • opendir関数/ readdirは呼び出しがRecursiveDirectoryIterator

  • 建物よりもはるかに高速です再帰呼び出しの深さを使用してディレクトリツリー最初または線形の違いはありません

上記のテストは、ローカルSSD、ローカルUSBおよびネットワークドライブ上で一貫した結果で実行されます。ギガビットやそれ以外の高速のReadyNASユニットにもかかわらず、ネットワークドライブでの実行はローカルドライブよりも最大180倍遅かったです!

1秒間に処理されるエントリ数は、最も低速のコードではネットワークドライブに、最も高速なコードではUSBドライブに約65 000(キャッシング)の範囲でした。

しかし、ネットワークドライブの大きな違いは、Linuxでの単純なdirコマンドとlsが同じファイルを使っているので、PHP内部で何が起こるのか不思議です。

続ける...

2

私はいくつかのテストを行った。 (建設用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サーバの結果:

scandir: 0.82553291320801 
readdir: 0.91677618026733 
glob : 0.76309990882874 

これは、4つのコア(8つのスレッド)インテルE3-1240 CPUのLinux + ApacheサーバからReasults。

しかし、Windows Serverの結果は正反対です。 Windowsの+ Apacheサーバ - インテルQ8400 4コア(4つのスレッド)

のWindows Server結果:私が知っている

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

scandir: 0.61557507515 
readdir: 0.614650011063 
glob : 1.92112612724 

(フォルダのファイルが増加している場合は、結果が異なる可能性が13個のファイルが含まれています。)

2

この質問は実際には現実的ではないかもしれませんが、私はいくつかのテスト(AufziehvogelとSayahanのような)をわずかな違いで実行しました。

$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; 

結果(HDD):

scandir:   1.9403479099274 
readdir:   0.79462885856628 
DirectoryIterator: 0.5853099822998 

結果(SSD):

scandir:   0.83593201637268 
readdir:   0.35835003852844 
DirectoryIterator: 0.28022909164429 

CPU:のRadeon(TM)HDグラフィックス(4つのコア)とAMD A10-4600MのAPU
MEM:8G
PHP:5.6.29

関連する問題