PHPのディレクトリ内ファイル名一覧の読み取り速度

シェアする

  • このエントリーをはてなブックマークに追加
  • Evernoteに保存Evernoteに保存

あるディレクトリ内に1万以上のファイルがある場合、FFFTPなどのFTPクライアントで一覧を表示させようとすると大変時間がかかります。

これはタイムスタンプなどの情報も取得したりするからだと思うのですが、「単純にファイル名の一覧だけが知りたいのに」という場合にPHPでチェックしたらFTPと同じくらい時間がかかるのか測定してみました。

まず、PHPでディレクトリ内のファイル名一覧を取得するには3通りの方法があります。

  1. opendir/readdir/closedir関数を使った方法
  2. dirクラスを使った方法
  3. scandir関数を使った方法

では、どの方法が処理が早いのか。

結論から言うと、速度的にはopendir/readdir/closedir関数を使った、開いて読んで閉じてと一手間かけた方が一番早いです。ほぼ変わらずで、(2)のdirクラスが次に早く、最後がscandir関数でした。

scandir関数は、呼び出すだけで配列で一覧を取得できるので、コード的には一番シンプルに使えるのですが、かなり遅いのでケース・バイ・ケースといったところでしょうか。

■平均速度

opendir/readdir/closedir関数 0.0260826086998秒
dirクラス 0.0282469367981秒
scandir関数 0.145169408321秒

速度測定には、14,498個のファイルがあるディレクトリを、下記スクリプトで各処理を100回くりかえし所要時間の平均をだしました。サーバはLolipop(チカッパ)です。

「なんだ1万5千ファイルのファイル名を呼び出すのに、1秒もかからないじゃまいか」と思うかもしれませんが、下記処理をたった300回繰り返すだけでサーバがタイムアウトします。

■測定用のスクリプト

<?php
function showResult($sMsg,$iCount,$iStartTime,$iEndTime){
$iDifTime = $iEndTime-$iStartTime;
echo "<h1>{$sMsg}</h1>読み取りファイル数:{$iCount}<br>所要時間:{$iDifTime}秒<br>";
}
/* ---------------------------------------------------------
        opendir/readdir/closedir関数を使った読み取り
       --------------------------------------------------------- */
$iCount = 0;
$iStartTime = microtime(TRUE);
$hDir = @opendir($sDir);
if($hDir !== FALSE){
while(($mFile = readdir($hDir)) !== FALSE){
$mDummy[] = $mFile;
$iCount++;
}
closedir($hDir);
}
else{
die("Error opening dir at '{$sDir}'");
}
unset($mDummy);
$iEndTime = microtime(TRUE);
showResult("opendir/readdir/closedir関数を使った読み取りテスト",$iCount,$iStartTime,$iEndTime);
/* ---------------------------------------------------------
        dirクラスを使った読み取り
       --------------------------------------------------------- */
$iCount = 0;
$iStartTime = microtime(TRUE);
$oDir = @dir($sDir);
if($oDir !== FALSE){
while(($mFile = $oDir->read()) !== FALSE){
$mDummy[] = $mFile;
$iCount++;
}
$oDir->close();
}
else{
die("Error opening dir at '{$sDir}'");
}
unset($mDummy);
$iEndTime = microtime(TRUE);
showResult("dirクラスを使った読み取りテスト",$iCount,$iStartTime,$iEndTime);
/* ---------------------------------------------------------
        scandir関数を使った読み取り
       --------------------------------------------------------- */
$iCount = 0;
$iStartTime = microtime(TRUE);
$aDir = @scandir($sDir);
if(is_array($aDir)){
foreach($aDir as $key=>$mFile){
$mDummy[] = $mFile;
$iCount++;
}
}
else{
die("Error opening dir at '{$sDir}'");
}
unset($mDummy);
$iEndTime = microtime(TRUE);
showResult("scandir関数を使った読み取りテスト",$iCount,$iStartTime,$iEndTime);

スポンサーリンク
レクタングル(大)広告

シェアする

  • このエントリーをはてなブックマークに追加
  • Evernoteに保存Evernoteに保存
スポンサーリンク
レクタングル(大)広告