phpで処理速度アップを考えています。


今は switch foreach if が入れ子状態で、
4階層くらいまで入れ子になってます。

foreach($a as $b){

で始まり、このループを「1周」するだけなら
なんとかなるのですが、
「3周」ほどすると、えらい時間がかかってしまいます。

いろいろ工夫してみてますが、
あまり劇的な進化ができなくて頭打ちになってしまいました。

処理速度をアップさせる方法で、
幅広くアドバイスを頂けるとうれしいです。

phpで外部ファイルを読み込み、処理し、出力しています。mysql等は使っていません。
関数や設定ファイルは別ファイルを読み込んでいます。

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2007/06/29 16:55:02
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答2件)

id:studioes No.1

回答回数523ベストアンサー獲得回数61

ポイント35pt

 チューニングは実際のコード次第になりますが・・・

 良くやるのはコードが冗長になっても、制御構造を減らすと言う方法ですね。 これは、共通部分の前後で同じ条件でifする場合に、1回のifにして共通部分も両方書いてしま等です。

 for($i=0; $i<count($a); $i++)の様な処理を、for($i=count($a);$i>0; $i--)にする等も効果があったりしますね。 関数を読ぶとコストが増えるので、同じ結果を取るべき物は、一度変数に入れてしまってそれを使い回すわけです。

 演算処理で求める値について、演算コストが高ければ、ある程度演算結果表を定義しておいて、そこから読み込むという方法等もあります。

 また、出力処理はコストが高いので、内部で何度もecho等を使っている場合には、$out .= strの様にして、変数に連結していって、最後にecho($out)等とするのも効果がある場合があります。

id:onigirin

どうもありがとうございます。

制御構造を減らす、ですね。

コードの可視性とスマートさ・後で見たときのわかりやすさメインにしていました・・・。

細分化して関数も無意味なものまであるのが微妙な原因ですね。

早速全ての項目についてチェックしてみますね。

どうもありがとうございます!

2007/06/22 20:54:20
id:bonlife No.2

回答回数421ベストアンサー獲得回数75

ポイント35pt

どこで時間がかかってるのか測定してみてはいかがでしょう。

PEARのBenchmarkを使って、こまめに分割して計測してみれば、どの処理に時間がかかっているのか分かる可能性があります。

[参考]

その後、リファクタリングです。

id:onigirin

どうもありがとうございます。

これは便利ですね。

早速使ってみたところ、時間のかかっているところが見えてきました。

PEARはホント便利ですね・・・。

使ってみると、ベンチマーク計るのが楽しくなってきました。

リファクタリングのサイトも参考に、改善してみます。

どうもありがとうございます!

2007/06/22 22:25:21
  • id:Sampo
    forループが4階層というのは、システムのチューニング以前にアルゴリズムに工夫の余地があるのではないかという気がします。
    3段階入れ子でさえ、必要になることは滅多にありませんから……

    もし処理内容まで示していただけたら、もっと階層の少ないループを考案できる(私なり、ほかの誰かなりが)かもしれません。
  • id:onigirin
    どうもありがとうございます。

    3つほど設定したRSSを取得してパースしているだけなのですが、
    今見たら最大6階層までいってる部分がありました。

    例えば
    http://b.hatena.ne.jp/keyword/%e3%81%af%e3%81%a6%e3%81%aa?mode=rss
    こういうようなrssをはてなに限らず3つほど取得しているのですが、
    ・3回繰り返す foreach
    ・rssがレスポンスエラーかチェック if
    ・rssのデータ内のitem回繰り返す foreach
    ・dc:subjectのような複数個ある要素を取得 switch
     (rssによって構造が違うのでswitchで分けてます)
    ・dc;の数だけループ while
    ・その中で重複かチェック if
    という感じで、6階層目まで最大いってます。
    他の小さな処理も4階層などいろいろあるのですが、
    最大階層はここまでいってます。

    できるだけ同じコードを書かないでいいようにしてたら、
    えらい階層が深くなってしまいました。

    流れはパッと見てわかりやすいのですが、
    階層深いなぁ・・・と中途半端な感じですね。。。
  • id:bonlife
    処理の内容は必要に応じて関数などにした方が分かりやすそうですね。
    例えば、3つ設定したRSSを処理する、と考えるのではなく、RSSを1つずつ処理する関数(parseRssとかそんな名前の関数)を用意し、3つのRSSを1つずつその関数に渡して処理する、などとした方がソースも読みやすくなると思います。

    また、RSSのパースであれば、ライブラリを使った方が楽ですよ。
    以前はMagpie RSS ( http://magpierss.sourceforge.net/ ) も人気があったようですが、最近はSimplePie ( http://simplepie.org/ ) が良さそうです。(完全に主観です。)
    SimplePieは simplepie.inc という1つのファイルで出来ていますので、このソースコードを読んでみると面白いかもしれません。
    フィードを処理する init() という処理が1325行目から1670行目あたりにあり、これを見ると、if文が8階層ぐらいまでネストしているようです。
    階層が深くなること自体を問題視することもありますが、時には必要だ、ということではないでしょうか。
  • id:onigirin
    どうもありがとうございます。
    確かにもう少し関数化した方が見やすいかもしれませんね・・・。

    そういえばMagpieとかありましたねぇ。
    すっかり忘れていました。
    php5のxml関数がすごいので感動して使いまくってました。。。

    早速チェックしてみますね。
    階層についても、処理スピードを見ながら調整してみたいと思います!

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません