- ベストアンサー
foreachを使わず、必要な文字列を全部抜き出す。
HTMLから株式情報を抜き出すCGIを定期的に実行しているのですが 大量のHTMLをforeachで一行ずつ処理しているせいか 非常に動作が遅いです。 そこでそのほかの方法がないか考えてみましたが なかなか思いつきません。 何かよい方法はないでしょうか? 以下のソースは現在私が使っている方法を 簡単に書いてみました。 ------------------------------------------------------ @{html}=( "abcdefghijklmnopqr1stuvwxyz", "abcdefghijklmnopqr2stuvwxyz", "abcdefghijklmnopqr3stuvwxyz", "abcdefghijklmnopqr4stuvwxyz", "abcdefghijklmnopqr5stuvwxyz", "abcdefghijklmnopqr6stuvwxyz", "abcdefghijklmnopqr7stuvwxyz", "abcdefghijklmnopqr8stuvwxyz"); #あまりよろしくなさそうな方法 foreach ${_}(@html){ $top=index(${_},"r"); $end=index(${_},"s"); $result=substr(${_},$top+1,$end-$top-1); print"$result<br>"; } ------------------------------------------------------ できれば、@{html}を一行ずつ処理するのではなく ${html}から正規表現などで一気に数字(必要な箇所)だけ 抜き出せれば理想です。 質問の仕方がへたくそで申し訳ないです。 わかりにくい箇所などはいっていただければ 随時追加の説明をします。 どうぞよろしくお願いします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
まず簡単なのは、 foreach ${_}(@html){ の1行を以下のいずれかに変更する事でしょう。 for( my $ii = 0; $ii < @html; $ii++ ) { $_ = $html[$ii]; または while(@html) { $_ = shift(@html); これで、 @html の要素数の多さに起因する負荷(仮想空間占有)は軽減されるかも知れません。 Perlの文法だけに頼るのは上記位でしょうか。 あとは、プログラミング・テクニックの実力での勝負になります。 簡単なのは、負荷の高い標準関数等を別のものに置き換える事ですが、それにはソースコードの行数では無く内部負荷に注目できる経験が必要です。 実のところ、プログラムの高速化というテーマは極めるにはとてもとても難しいのです。 言語の特性から扱うデータの傾向を把握して、かつそれらを咀嚼して総合判断できる経験が必要です。 例えば、@html の収集が完了してから処理するのは多くの場合不利です。 要素 1件を収集したらすぐに処理して、次の1件の収集する時にはもはや不要な事柄を記憶するメモリは開放しましょう。 (free() とかの開放関数はありません。 my を上手に使いましょう) > ${html}から正規表現などで一気に数字 "abc123d456ef" =~ m/(\d+)\D+(\d+)/; my $num1 = $1; # 123 my $num2 = $2; # 456 正規表現も index() も負荷はちょっぴり高い処理なので、どれだけ速くなるかはデータ次第かも。
その他の回答 (2)
- Tacosan
- ベストアンサー率23% (3656/15482)
「できれば」のところが謎. @html と $html の関係は? それはおいても, #2 が言われるように「本当に時間がかかっているのはどこか」をきちんと把握しないと駄目でしょうね. 実はメモリが逼迫してるために遅くなってる, とかいうオチだったりして.
お礼
質問内容がわかりにくかったので申し訳ありません。 なんとか改善できそうです。 ご回答ありがとうございました。
- t-okura
- ベストアンサー率75% (253/335)
「あまりよろしくなさそうな方法」を1万回繰り返してみましたが、 atom 1.6GHz というたいして早くないCPUでも、CPU 時間は 0.5秒 使って いませんでした(print の出力は /dev/null に捨てています)。 本当に「大量のHTMLをforeachで一行ずつ処理している」のが遅い原因なの でしょうか。いちど Devel::DProf 等を使ってプログラムのプロファイル を取ってみてはいかがでしょう。 ちなみに数字を抜き出す方法として、 tr /a-zA-Z//d # 数字以外を削除 index と substr # 数字部分を substr で抜きだし /(\d+)/ # 正規表現で抽出 を試してみたら、この順に早かったので、「あまりよろしくなさそうな方 法」も捨てたものではないです。
お礼
質問をした後色々と調べてみたところ ネット上からHTMLを取得する段階でかなりの時間を使っていたようです。 これは取得先のサーバーの応答速度の兼ね合いもありますので 改善しにくい問題でした。 foreachについて言えば foreachの中で、山のように関数やら文字列処理を繰り返していた ことも遅くなっていた原因のようです。 いずれにせよ、真摯なご回答ありがとうございました。 ポイントはあげられませんでしたが、参考になりました。
お礼
なるほどそういう処理の仕方があるのですね。 早くなるか試してみたいと思います。 正規表現の負荷が高いのは参考なります。 "正規"とついているので一番負荷がかかりにくいのかと思ってました。 色々ありがとうございます。