-PR-
解決済み

Perl 速度について

  • 困ってます
  • 質問No.9385047
  • 閲覧数237
  • ありがとう数3
  • 気になる数0
  • 回答数3
  • コメント数0

お礼率 75% (6/8)

あるサイトの情報を取得するのに
ソースを組んで、なんとかできたのですが、

時間がかかってる気がします。
ページ数 約300ページくらい読み込んでいて
その中でも、
250ページほど、正規表現で、一部抜粋し、保存させているのですが、
ここが遅いです。
保存した容量は、
1個につき2kb~20kb
平均8kbほど

下記のような、ソースの箇所が明らかに遅い気がします。
my @words;
while ($content =~ m#<td.*?>(.+?)</td>#gs) {
my $word = $1;
$word =~ s/<.+?>//g;
$word =~ s/(\r|\n)+/\,/g;
$word =~ s/,+//g;

for( my $year=2010; $year<2017; $year++ ){
$word =~ s/$year\//\n$year\//g;
}

from_to($word,"euc-jp","utf8");
utf8::decode($word);
push(@words, $word) if $word;
}
@Word = join(',', @words) . "\n";

print @Word;
open(FILE, ">","$DATA[$i].txt") or die("error :$!");
flock(FILE, 2);
print FILE @Word;
close FILE;

内容が多いからでしょうか?
だいたい10分近くかかっております。
パソコンもcore i3と古い
Windows7を使用しています。

そんなものでしょうか?
もしくは、速くする方法はありますか?
通報する
  • 回答数3
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

質問者が選んだベストアンサー

  • 回答No.3
レベル10

ベストアンサー率 66% (81/121)

やっぱり、LWP を使って http 通信を行っているのですね。
おそらくはhttp通信の応答時間が10分という時間がかかる原因でしょう。

私も以前(15年ほど前)に、ほぼ同じような仕組みを作ったことがあります。
そのときは LWP::UserAgent ではなく、get だけでよかったので LWP::Simpleを使いました。
確か30ページ程度を取得し、得られた内容から任意の値をファイルに書き込むスクリプトだったのですが、15秒~20秒程度で完走したように記憶しています。
[注意] 対象サーバによっては、getだけの用途でもLWP::Simpleが使えない場合があります。

get だけで良い and 対象サーバが応答してくれれば、 LWP::Simple を使うのも手と思います。

さらに、最近では Furl というモジュールもあるようです。
http://search.cpan.org/~tokuhirom/Furl-3.13/lib/Furl.pm
私は使ったことがありませんが、LWP との比較で2.5倍程度高速らしいです。(ローカルでの検証)
お礼コメント
bakanandesu

お礼率 75% (6/8)

お返事が遅くなり申し訳ないです。

色々試してみておりました。

Simpleは、実行できませんでした・・・
Fullもインストールしてとの指示でインストールしたのですが、
使用できませんでした。

もう少し自分で調べてみます。
また、わからないことがあったらよろしくお願いいたします。
投稿日時 - 2017-10-17 14:59:23

その他の回答 (全2件)

  • 回答No.1
レベル10

ベストアンサー率 66% (81/121)

こんばんわ。
一部、何をやりたいのか良くわからない箇所もありますが、文字コードのエンコードとデコード部分を while ループの外に置くと少しは速度改善します。

@Word = join(',', @words) . "\n";
この部分ですが、join(',', @words) で得られる値は文字列ですので、次のように置き換えます。
$string = join(',', @words) . "\n";

その後で、エンコード・デコードを行えば良いです。
from_to($string,"euc-jp","utf8");
utf8::decode($string);

当然、ファイルに書き込む際は次のようになります。
print FILE $string;

ですが、ボトルネックは示されたコード以外の部分だと思いますよ。
お礼コメント
bakanandesu

お礼率 75% (6/8)

御回答ありがとうございます。
エンコード・デコードを外にもっていくと
少し速くなりました。


>ボトルネックは示されたコード以外の部分だと思いますよ。
一応、個々にテストを行って他の箇所は遅くはなかったのですが、
組み合わせることによって、遅くなったりするのかな・・・?
強いてあげるなら、my @words;
の上に、下記のソースがあります・・・


$num=3~5ほど
$DATA=サイト側の暗号的なもの

for( my $i=0; $i<$num; $i++ ){
our $URL = 'http://あるサイト/' . $DATA[$i] . '/';

my $proxy = new LWP::UserAgent;
$proxy->agent('your own created browser name here');
$proxy->timeout(60);
$req = HTTP::Request->new('GET' => $URL);
my $res = $proxy->request($req);
my $content = $res->content;

if($res->is_success) {
投稿日時 - 2017-10-13 09:23:17


  • 回答No.2
レベル9

ベストアンサー率 31% (22/70)

my $words;
while($content=~m[<td.*?>(.+?)</td>]gs){

my $word = $1;
$word =~ s[<.+?>|\n|\r][]g; # 文字コードeucで\rあるの?
$word =~ s[(201[0-6])/][\n$1/]g;

$words .= "$word," if $word; # 出来るだけ関数使わない
}

$words =~ s[,$][\n];

Encode::from_to($words,'euc-jp','utf8');
お礼コメント
bakanandesu

お礼率 75% (6/8)

ありがとうございます。
極力関数は使わないよう、考えてみます・・・
投稿日時 - 2017-10-16 13:01:04
このQ&Aのテーマ
このQ&Aで解決しましたか?
AIエージェント「あい」

こんにちは。AIエージェントの「あい」です。
あなたの悩みに、OKWAVE 3,500万件のQ&Aを分析して最適な回答をご提案します。

こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-

特集


抽選で合計100名様にプレゼント!

ピックアップ

ページ先頭へ