プログラムとデザイン(html)の部分を分ける為に、以下のようにしました。
// ファイルからデータを取得
$fp = fopen("log.txt","r");
$i=0;
while(!feof($fp)){
// ファイルから1行読み込み
$line = fgets($fp,1000);
// タブ区切りを配列にする
$array = explode("\t",$line);
// 表示用の配列に代入
$list[$i]["date"] = $array[0];
$list[$i]["ua"] = $array[1];
$list[$i]["host"] = $array[2];
$i++;
}
// 表示用
<?php for($i=0;$i<10;$i++){?>
<tr>
<td><?=$list[$i]["date"]?></td>
<td><?=$list[$i]["ua"]?></td>
<td><?=$list[$i]["host"]?></td>
</tr>
<?php }?>
※繰り返し箇所のみ掲載
しかし、上記の方法だと1万行の処理をするのに2~3秒の時間を要します。
一旦配列に代入しているので時間がかかるのは分かるのですが、
もしかしたら自分の書き方・考え方が間違っているのではないか?と思っています。
他に良い方法がありましたら、アドバイスいただければと思います。
※あくまでPHPとテキストファイルを使った上での実験ですので、DBを利用するという代替案は無しでお願いします。
※PHPは5.2.6を使っています。
上記の方法だと1万行の処理をするのに2~3秒の時間を要します
ご質問のソースを、前半の(a)データ取り込み部分、と後半の(b)表示部分に分けます。
(a)だけで2~3秒かかっていますか? であれば、サーバのスペックなどをお知らせいただけますか。
一般的には、(b)の処理――というより、(b)の部分をブラウザで表示させるのに圧倒的に時間がかかります。
とくに table タグは、ブラウザの表示処理に時間がかかります。
本当にブラウザ表示する必要があるのかどうか疑問なのですが‥‥まずは、(a),(b)のどちらに時間がかかっているのかご確認ください。
データ読込み部分に時間が掛かっているのは、ひょっとして1行毎に読んでいる為?
たぶんある程度はキャッシュ(というかバッファリング)されているとは思うのですけど...
それなりの量があれば、複数回ディスクにアクセスする事になるのでは?
データ量が多いと、file() で一気に読み込むってのも気が引けるなぁ...
ってよく見たら結局は配列に全部入れているんですね。
1行毎の処理と一気読みと速度差がどれほどあるのはチョッと不明です。
(1万行のサンプルデータを用意できないので、テスト不可...)
どうせ1行毎に読むなら、データを保持せずに書き出すまでやってしまうとか?
(処理内容によっては出来ないですけど)
PHPはデータを新しい配列に入れても、その内容が更新されるまでは参照で保持していると
読んだ気がします。
なので、出来るだけ内容を変更しないようなフローに変更すると処理が軽くなりませんか?
(かなり推測で書いてます...)
「推測で~」と書かれているので、明確に私のソースが悪いのか
他に良い書き方があるというわけでもないですよね?
例えば
「その書き方だとどうしても処理が遅くなるから○○した方が良い」
というご意見や参考URLをいただければと思い質問しましたので、
推測よりも答えがいただければ助かります。(もちろん答えは”回答”で)
適当なのが無かったので、ローカルに転がっていたファイルで読込みテストをしてみました。
全行同一書式で無いので読み飛ばし等の処理を追加。3万行ほど。
fgets() で1行毎に読み、分割して、$list へ挿入 ... 0.542 秒
file() で配列に一気に読み込み、foreach() で各要素を分割し $list へ挿入 ... 0.386 秒
なので、どうせ一旦全部を取り込むのなら、一気にやった方が良いようですね。
有意な差があるのかは微妙ですが。
「推測」なのは、裏付け(実証データ)を持ち合わせていない為です。
なので、fgets(), file() の比較テストをしてみました。
また、変数をコピーしても値が変更されるまで実際のコピーは行われない件も
読み込んだデータを全く何も処理せずに出力するとは思えなかったので、部分的にでも
そういう使い方(=内容を書き換えない)をすれば多少は早くなるのだろうとのつもりでした。
言葉足らずのコメントでごめんなさい。
tukihatuさんの回答で、他に方法がないと思い、質問を終了させました。
tezcelloさんがおっしゃる、fileを使う方法を試しました。
私の環境では1万件を取得して20件表示するのに、1~2秒かかりました。
質問時のソースよりは1秒短縮しました。
質問に書いたようなソースの利用方法は、「ログ保存」になりますが、Apacheをはじめ、他のプログラムでも割と保存にテキストファイルを使っているので、何万行の処理でもWEB用途に利用出来るのではないか?っと思い、実験していました。
ただ、おっしゃるように読み込んでデータになんらかの処理を加えるわけですから、どうしても処理が遅くなってしまいます。
もしかしたらログ保存の方法か表示方法に問題があるかも知れませんね。もう少し考えてみます。コメントありがとうございました。
一万件程度ならfileの方が確かにいいかも。
でもfileだと一旦全部を取り込むので、あんまりにも行数が長いと処理が止まったりします…
http://tt25.org/blog/20080510/each-lines
昔に質問したやつ
http://q.hatena.ne.jp/1208832776
参考になれば。