- ベストアンサー
PHPを使ったスピード重視の集計について
以下のログがあります。 --- 日付 時分 A B C カウント 2006/8/3 11:00 1 4 8 84 2006/7/4 17:04 3 5 4 47 2006/8/4 13:30 1 4 6 32 2006/3/3 15:15 5 1 8 8 2006/5/8 18:20 3 3 3 43 ・・・(以下、100万行位続く)・・・ --- このログを"時間"単位でA,B,C毎の"カウントを合計"したく、イメージとしては以下のテーブルを作りたいと思っています。(時間,A,B,Cの組み合わせでログに出て来なかったらテーブルに出力する必要無し。順番も特に問わない。) --- 日付 時間 A B C カウント合計 2006/8/3 11 1 4 8 84323 2006/8/5 13 4 8 3 9793 ・・・・ --- 処理スピードを重視して、メモリ上で行う前提で以下の方式を考えました。 多段配列を使い、ログが出るたびに $count["2006/8/3"]["11"]["1"]["4"]["8"] = 7672 のような配列を作ります。もし、配列があるのならカウント部分を足し算します。 最後に配列全部をファイルに書き出すという方法です。 しかし、ログの量があまりにも多くやはり処理時間がかなりかかります。またプログラムも多段配列の表記にすると非常に見辛い状態です。何か別のアルゴリズムか手法により、スピード重視で処理する方法をご存知であればご教授ください。 前提がPHPを使わなければいけない&DB使えないという環境です。 よろしくお願いします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
# 2です。 ちょっと気になって簡単なスクリプトで試験してみました。 一旦配列に格納し、それを集計、というものをfor,while,foreachでやってみました。 結果としては、forとwhileの差はほんの数パーセントで、ほとんど変わらなかったです。 概ねのベンチ結果は平均で for 2.82に対して、while 2.79です。 foreachでは $i<$cnt のような判断式が無いせいかずっと速かった(1.55)です。 配列を展開しながら繰り返す場合はforeachがベストなようです。 > かなりの時間は1時間程です。 冗談ならないですね。この手はcronで夜中にでもやらないとしょうがないですね。 ひょっとしたらPHPではなくC++やシェルを使ってプログラミングし、外部スクリプト(exec関数)で呼び出す、と言う方が速い可能性も高いですね。 また、1時間ということでしたら、ディスクアクセスの時間は十分小さくなるので、ディスクを使ってメモリをうまく解放させる方が速いかもしれません。 では。
その他の回答 (3)
- taketan_mydns_jp
- ベストアンサー率58% (450/773)
# 2です。とりあえず下記URLに結果等を公開しました.
お礼
すごい!! 大変参考になります。配列に入れてforeachでループさせたほうがかなり早いのですね。 大変参考になりました。ありがとうございます。
- taketan_mydns_jp
- ベストアンサー率58% (450/773)
100万行ですか、凄いですね(笑。 かなり時間がかかる、のかなりはどれくらいですか? メモリ上で行なっていても、サーバの設定によってはメモリ上で行なわれなくなっている可能性もありますね。 php.iniの設定を変えてみて試験してみるのも一つの手かもしれません。 メモリで一杯になってしまっていた場合、ある程度のところでファイル書き出ししながらの方が速い可能性もあります。100万行ならば、桁数だけでも1メガな訳ですから、読込まれたデータだけでも相当なメモリを消費する可能性があります。1万行(あるいはもっと小さくても)ずつ処理した方が速いかも?しれません。 forよりはwhileの方が速い、と言う話もあります。 http://www.sound-uz.jp/php/test/first1.html 関数を使うより自作スクリプトの方が速い場合もあると思います。 サーバ環境、設定によって条件は左右されると思いますので、いくつか試してみて、最速の方法を見いだして下さい。出来れば、その結果を公開して下さい(笑。 参考まで。
お礼
コメントありがとうございます。 かなりの時間は1時間程です。早い感じもするのですが、もっと高速化を図りたいと思っています。 php.iniで使用メモリの設定もできるのですね。調べてみます。 forよりwhileの方が早い話、大変興味があります。話がそれますが、このような話好きなんですね。ちょっと研究して公開してみます。(笑
- moon_night
- ベストアンサー率32% (598/1831)
日付ごとや月ごとに予め計算されたデータを作っておいて、そこから読み出すと言うのはダメですか?
お礼
ループ文の種類によって速度が違うということは非常に驚きです。 他言語を使ってという事も考えられるのですが、利用制限がありPHPしか使うことができないという苦しい状況なのです。 Try&Errorでなんとか比較しながらやってみたいと思います。コメントありがとうございました。