1]哪個功能更快?
2]有什麼區別?
readdir vs scandir
Differences
1]的readdir返回目錄下一個條目的名稱。 Scandir從目錄中返回一組文件和目錄。
2] readdir必須打開資源句柄,直到讀取所有條目。 scandir,可能會創建一個包含所有條目的數組並關閉資源句柄?
1]哪個功能更快?
2]有什麼區別?
readdir vs scandir
Differences
1]的readdir返回目錄下一個條目的名稱。 Scandir從目錄中返回一組文件和目錄。
2] readdir必須打開資源句柄,直到讀取所有條目。 scandir,可能會創建一個包含所有條目的數組並關閉資源句柄?
剛開結果(什麼也不做),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()編寫另一個循環,它會變慢。
這真的取決於您對數據所做的事情。
如果您要逐條輸入,則應該使用readdir
,如果您確實需要列出內存條目,則應該使用scandir
。
無論如何將信息複製到內存中無論如何你都要逐條使用它。在這種情況下,懶惰評估絕對是最好的選擇。
我會想象,scandir
只是一個圍繞readdir
調用相同的東西的包裝,因此會更慢。
做了一些更多的時間比較讀取整個目錄樹,用大量的文件和目錄:
通話文件類型()==「目錄」明顯快於is_dir()調用
的執行opendir/readdir的調用比RecursiveDirectoryIterator
建築快得多第一或線性使用遞歸調用深度的目錄樹沒什麼區別
其中在Windows一致的結果,進行本地SSD,本地USB和網絡驅動器的上述試驗。在網絡驅動器上運行的速度比本地驅動器慢180倍 - 儘管千兆和其他快速的ReadyNAS設備!
每秒處理的條目數從115到最慢的代碼到網絡驅動器到65000代表最快的代碼到USB 3.0驅動器 - 當然是由於緩存。
但是,網絡驅動器的巨大差異使您想知道PHP內部會發生什麼,因爲簡單的dir命令和ls在Linux中通過相同的文件更快。
待續...
我已經做了一些測試。 (感謝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
這Reasults從4芯(8個線程)英特爾E3-1240的Cpu LINUX + Apache服務器。
但Windows服務器結果相反。的Windows + Apache服務器 - 英特爾Q8400四核心(四個線程)
的Windows Server結果:
$count = 10000; // it was on linux 100000 :)
scandir: 0.61557507515
readdir: 0.614650011063
glob : 1.92112612724
(文件夾包括13個文件,如果文件是增加,結果可能會有所不同。)
我知道這個問題現在可能不是現實的,但爲了追加,我已經做了一些測試(如Aufziehvogel和Sayahan),它們有一個小小的區別 - 在一個有1,000,000個小文件(幾個字節)的目錄上。
$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:AMD A10-4600M APU用的Radeon(TM)HD圖形(4芯)
MEM:8G
PHP:5.6.29
可能的重複[使用PHP的數組目錄](http://stackoverflow.com/questions/2120287/directory-to-array-with-php) – salathe 2012-01-01 11:35:28