トップページ⇒php
1001コメント371KB

Perlコーディング初心者質問スレ Part 50

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん2006/06/26(月) 00:46:38ID:???
Perlのコーディングで困ってる人のスレです。

【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。

1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。

最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。

過去ログやお勧めサイトは >>2-10
0413nobodyさん2006/07/11(火) 22:06:01ID:???
a lt o だから
0414nobodyさん2006/07/11(火) 22:06:29ID:???
簡単に言えば、
・一文字目は両方ともhで同じ('h' eq 'h')。
・二文字目はaよりもoのほうが後にある('a' lt 'o')
ので、hageよりもhogeのほうが大きい、と判断される。
この一文字一文字の比較はバイト列として行われるから、詳しくはASCIIコード表をじっくり眺めてくれ。

ちなみに、数値しか入ってこないはずの日時の比較になぜ文字列比較をしたのかと言うと。
この場合はまだ良いんだけど、後数桁増えた場合、数値として扱うと誤差が発生するため、固定長の場合は習慣的に。
> print 20060711213959123456;
2.00607112139591e+19
> print 20060711213959123456 < 20060711213959123455
1
0415nobodyさん2006/07/11(火) 22:24:42ID:???
よくわからんがごちゃごちゃ変なことやらずにはじめからunix timeで(timeの戻り値をそのままで)
保持しておけば比較も簡単だと思うのだが、なぜわざわざ話をややこしくしたがる奴が多いの
だろうか。
0416nobodyさん2006/07/11(火) 22:51:13ID:???
DARK SIDE OF TIMTOWTDI
0417nobodyさん2006/07/11(火) 23:02:30ID:???
初心者スレだからあえて突っ込こんどく。

ほんとに誤差がでるの?@5.8.8
-------------
$\ = "\n" ;
print 20060711213959123456;
print 20060711213959123456 > 20060711213959123455
-------------
2.0060711213959e+20
1

自分の環境に合わせて、lt を使うかどうか判断しましょう
0418nobodyさん2006/07/11(火) 23:07:10ID:???
>>415 に同意
書くときに localtime なりすればいいわけで、
これならたとえ 西暦 から ともだち暦 に変わったってデータの変更とか必要ないしな。
0419nobodyさん2006/07/11(火) 23:09:27ID:???
lt知らなかったけど、可読性が下がる方向性しか見えてこないw、
0420nobodyさん2006/07/12(水) 00:23:20ID:qvG7JsXw
perl初心者です。
今CGIを制作しているのですが、正規表現でおもいっくそ躓きましたorz

例えば「$nameが5文字以上、100文字以下でなければエラーを実行する。」
みたいな感じに「$name」に文字制限を掛けたいのですが・・・。
よろしくお願いします。
0421nobodyさん2006/07/12(水) 00:31:07ID:cb+ZHaYE
length($name)
0422nobodyさん2006/07/12(水) 00:35:00ID:qvG7JsXw
>>421
すいません。ありがとうございます・・・。
しかし、悩んでいるのはその先なんです・・・。それをどのように正規表現のパターンにはめればよいか・・・。
0423nobodyさん2006/07/12(水) 00:40:55ID:???
正規表現じゃなくて、length() を使って条件分を書けば良いだけ
0424nobodyさん2006/07/12(水) 00:42:25ID:???
>>420
正規表現で何がしたいのか書いてなくね?
0425nobodyさん2006/07/12(水) 00:54:54ID:qvG7JsXw
>>424
「5文字以上、100文字以下」であることを調べたいと思ってるんですが・・・ orz
0426nobodyさん2006/07/12(水) 00:57:04ID:???
unless (5 <= length($name) and length($name) <= 100) {
&error;
}
0427nobodyさん2006/07/12(水) 01:01:22ID:???
翻訳します。

質問:
5文字以上100文字以下の文字列にマッチする正規表現が書きたい
回答:
出来無くないけど正規表現の使い方間違えてるよ
0428nobodyさん2006/07/12(水) 01:03:57ID:???
unless ($name =~ /^.{5,100}$/) {
&error;
}
0429nobodyさん2006/07/12(水) 01:06:52ID:w3I1i8Fs
print 2+4*3/2-1; # 7
print (2+4)*3/2-1; # 6(8が正しいはず)
print int((2+4))*3/2-1; # 8
となるのは何故でしょうか?
04304202006/07/12(水) 01:13:25ID:qvG7JsXw
あぁ・・・もう・・・
こんな低レベルな質問に・・・本当にありがとうございました orz
0431nobodyさん2006/07/12(水) 01:13:29ID:cb+ZHaYE
print (2+4)         *3/2-1;
0432nobodyさん2006/07/12(水) 01:17:09ID:???
納得しましたorz。ありがとうございました。
0433nobodyさん2006/07/12(水) 01:28:20ID:???
$hoge = "a,b,c,d,e,f,g,h,................";
と「,」で区切られた文字列があるとして
その中の冒頭部分のいくつかの要素が欲しいとき
どうするのが一番メモリ食わずに済みますか?
例えば、上の文字列からbとcとdが欲しい場合、
(undef,$hage1,$hage2,$hage3,undef) = split(/,/,$hoge);
とするのがベストなんでしょうか?
0434nobodyさん2006/07/12(水) 01:38:13ID:???
まぁ、しょうがないんじゃないの?
あとはsplitした結果の配列スライスを取るしかないね。
正規表現は処理として重いし。
データが絶対に1文字なら、substrで切ってからsplitするとか。

データが5000とかあって、3番目から100個取りたいとかいう事でなければ、
あまりメモリを気にしてもしょうがないよ。
perl使ってる時点で、かなりのメモリを喰ってる訳だから。
04354332006/07/12(水) 01:46:55ID:???
>>434
ありがとうございます。
多少のことなんか気にせずバリバリ書く方が気楽なんですけどね。
省メモリに凝りだすと、ついついつまらないことまでも気になって眠れませんw

ちなみにものすごくどうでも良いことだとは思うんですが
(undef,$hage1,$hage2,$hage3,undef) = split(/,/,$hoge);
と
(undef,$hage1,$hage2,$hage3,) = split(/,/,$hoge);
って、あらゆる点から見て全く同じ処理という解釈で良いんですかね?
0436nobodyさん2006/07/12(水) 01:52:13ID:???
小手先だがsplitに第3引数を与えて余計な分解はしないようにするといいよ

(undef,$hage1,$hage2,$hage3,undef) = split(/,/,$hoge,, 5);
0437nobodyさん2006/07/12(水) 02:05:31ID:???
>>435
質問の答えじゃないですが
perldoc -f split
で第3引数のLIMITを見てみて。単純にsplitするよりは効率いいかも。
04384332006/07/12(水) 02:18:09ID:???
>>436-437
なるほど、どこまで読み込むかの範囲指定できる引数を割り当てられるんですね。
って、以前にsplitの項を本で読んだときに絶対目にしてるはずなんだけどなぁ。
実際に使わないと身に付かない体質なのか・・・。
これは付けておくに越したことはないですね。可読性の点からも悪くないですし。
即、該当箇所全てに割り振らねば!
ありがとうございました!

undefで値を捨てるのと、そもそも値を未定義(?)にしておくのと何か違いがあるのか
分かる方いらっしゃいましたら、お暇なときにでも教えて下さい。
0439nobodyさん2006/07/12(水) 02:44:06ID:???
>>435
>ちなみにものすごくどうでも良いことだとは思うんですが
>(undef,$hage1,$hage2,$hage3,undef) = split(/,/,$hoge);
>と
>(undef,$hage1,$hage2,$hage3,) = split(/,/,$hoge);
>って、あらゆる点から見て全く同じ処理という解釈で良いんですかね?

上はそのまま。
下は、
(undef,$hage1,$hage2,$hage3) = split(/,/,$hoge);
に最適化される。
0440nobodyさん2006/07/12(水) 02:56:50ID:???
左辺にundef置いても警告されないんだ。いい事聞いちゃったw
0441nobodyさん2006/07/12(水) 04:55:16ID:???
どうでもいいがundef 書くくらいだったら
my ( $hage1,$hage2,$hage3) = ( split/,/,$hoge)[1,2,3] ;
てスライス使わない?


0442nobodyさん2006/07/12(水) 09:45:38ID:???
>>438
> これは付けておくに越したことはないですね。可読性の点からも悪くないですし。
> 即、該当箇所全てに割り振らねば!

何も考えずに即値をばらまくと後できっと忘れます。やるならコメント推奨。


> undefで値を捨てるのと、そもそも値を未定義(?)にしておくのと何か違いがあるのか
> 分かる方いらっしゃいましたら、お暇なときにでも教えて下さい。

undef って書かなくていいので、楽ちんな上にプログラムサイズを小さくすることができます。
いや正直「そもそも値を未定義(?)にしておく」が、どういう操作を指しているのか分からないので分かりません。
0443nobodyさん2006/07/12(水) 10:47:13ID:???
>>420
日本語が含まれるのかどうかについて誰も触れていないんだが?
0444nobodyさん2006/07/12(水) 11:35:39ID:???
>>441の方法が普通だよな。
(undef,$hage1,$hage2,$hage3) = split(/,/,$hoge);
なんて酷いの始めてみた。
0445nobodyさん2006/07/12(水) 11:38:48ID:???
特に酷いとは思わない俺ガイル
0446nobodyさん2006/07/12(水) 11:50:40ID:???
>>444
undef を左辺に置く手法は、何番目の要素をそれぞれ拾い、捨てているのか視覚的に分かりやすいというメリットもある。
リストの要素数が小さく、かつ一定である場合には特に。
0447nobodyさん2006/07/12(水) 11:55:26ID:???
ダミーを用意しなくてもいい
スライスしなくてもいい
を考えて、warningが出ないなら有用だと思うが
04484412006/07/12(水) 12:13:35ID:???
軽い違和感を感じただけだから、>>446-447 の意見で納得した。
まあ機会があれば使うかもしれん。
>>393
>print @{[split /;/,$temp]}->[1];
の方は「 split のケースでは」一生使うことはない。

0449nobodyさん2006/07/12(水) 14:25:53ID:???
プチ天狗になりそうだった自分を戒めてくれる流れだわ。
0450nobodyさん2006/07/12(水) 16:11:36ID:x2NzMLn/
foreach $line (@log) {
 foreach $keyword (@keywords) {
  if ( index($line, $keyword) >= 0 ) {
    push (@result, $line);
    last;
  }
  }
}

こーんな感じで検索してるんだけど、
@keywordsの中身がHitしても次の行に行ってくれない、
というか@keywordsの複数の中身がhitすると同じ行が何回もpushされちゃう。
なんでなんでしょうか?
0451nobodyさん2006/07/12(水) 17:18:49ID:???
>>450 のループ自体は正常に結果を吐くので他の要因だと思われ。
つーか index をそう使うの初めて見た
0452nobodyさん2006/07/12(水) 20:58:47ID:???
grep
0453nobodyさん2006/07/12(水) 21:00:13ID:???
>>446
視覚的にとかいう意味だと、スライスの方が数字なんだし読みやすい希ガス。

>>451
探す文字がパターンマッチを必要としないならindexの方が激速。
0454nobodyさん2006/07/12(水) 21:01:33ID:???
復旧!
テストカキコついでに>>392 への遅レス
ダークサイドだが
my @date = grep {$_} split /(\d2})/, '060711' ;
ちう手もあるよん。
0455nobodyさん2006/07/12(水) 21:04:03ID:???
>>454
ひどいな、そのコード…。
普通にunpackが一番早かろうに
0456nobodyさん2006/07/12(水) 21:10:09ID:???
{ がぬけてもた。 /(\d{2})/ ね
>>454
そw 普段こんなの絶対使わないw
が、たまに
my $i = 0;
my %hash = map { $_ or $i ++ } split /(.{20})/, $hoge ;
とかしたくなって誘惑される。
だからダークサイド。
0457nobodyさん2006/07/12(水) 21:24:50ID:???
>>453
>探す文字がパターンマッチを必要としないならindexの方が激速。
なるほど…今度使ってみよう。
>>456
それって20で割り切れなかったら…
まあ、承知のうえで書いてんでしょうけど。ダークサイド宣言してるし。
0458nobodyさん2006/07/12(水) 21:26:14ID:Fw7S49xF
質問です。

perlで書かれたあるcgiからhtmlを読んでその中身を表示したいのですが、さらに一歩踏み込んで、そのhtmlの中でさらにperlで書かれたcgiを呼んで、そのhtmlを動的に変更して表示したいのですが、そんなこと可能ですか?
0459すいません…2006/07/12(水) 21:50:43ID:???
ものすごく初歩的な事をお伺いして申し訳ないのですが、activeperlを
ダウンロードしたのですが、コマンドプロンプトでバージョンチェックを
しても、「バッチファイルとして認識していません」と表示されるのですが
どうすれば良いのでしょうか?
0460nobodyさん2006/07/12(水) 21:51:10ID:???
>>457
一応対応はできる、がこんなことするくらいだったら
普通に hash 作成すべき。

split /(.{20})/, $hoge ;
push @_, '', pop @_ if @_ % 20 != 0 ;
my $i = 0;
my %hash = map { $_ or $i ++ } @_ ;

04614602006/07/12(水) 21:59:24ID:???
s/20/2/
orz...吊ってくる
04624602006/07/12(水) 22:03:56ID:???
@_ % 2 != 0 ;
スレ汚しすまん
0463nobodyさん2006/07/12(水) 22:36:08ID:???
質問させてください
Perlでシェルスクリプト(useradd)を使用するにはどうしたらいいでしょうか?
0464nobodyさん2006/07/12(水) 23:02:43ID:???
>>458
なんでそんなことせにゃならんのかかわからんがSSIでも使えば?
0465nobodyさん2006/07/12(水) 23:03:43ID:l/BVmrr1
今WinXPとActivperlでプログラム作ってるんですが
これってPerlユーザーの主流じゃないようなんですが
何故ですか
0466nobodyさん2006/07/12(水) 23:08:41ID:???
>>463
system "your script" ;
もしくは your script をバッククォートにてかこむ。
your script 部分にはコマンド単独実行時の
打ち込むものすべてを入れる。
0467nobodyさん2006/07/12(水) 23:18:33ID:???
>>466さんを参考に以下を実行してみました。
#!/usr/bin/perl

$user = "aaa";
system "useradd $user";

エラーは出ないのですが、ユーザーが追加されてません。
なぜでしょうか?
0468nobodyさん2006/07/12(水) 23:30:16ID:???
useradd ってコマンドがあるのね orz...

具具ってみたけど
useradd って管理者権限が必要でしょ。
sudo useradd か perl 自体の実行を su でするか
しないとだめなんじゃない?

力になれそうにありません。すまん。
0469nobodyさん2006/07/12(水) 23:39:41ID:???
>>468さんありがとう
ちょっと質問変えてみます
Perlでシェルスクリプト実行するにはどうしたらいいでしょうか?
04704462006/07/12(水) 23:41:57ID:???
細かい話になるけれど。

>>453
> 視覚的にとかいう意味だと、スライスの方が数字なんだし読みやすい希ガス。

もちろんそりゃ読みやすいほうを使ったらよろしいんです。いつでもどちらかがイイってな話はしてないですから。

「視覚的に」と言うからには、数値のリストを添字として読み、それを元にスライスされる前のリストからどの値を取り出してどの値を捨てたのかを、脳内変換すること無しに、その姿を *目で見て* 把握できることを指しています。
逆から言えば、その意味では添字によるスライスの表現は、左辺 undef と比較した場合、視覚的ではないと言わざるを得ないでしょう、ということです。
0471nobodyさん2006/07/12(水) 23:43:05ID:3OAigznj
perlやっててmysqlでつまづきました
CGI経由でsql文を実行しようとすると動きません
コンソールからやっても動かないのでsql文がおかしいと思います。

mysql> update todo set content = aho where id = 9;
ERROR 1054 (42S22): Unknown column 'aho' in 'field list'

以上のエラーが出ています。
mysqlのバージョンは4.1.13です。
よろしくお願いいたします。
0472nobodyさん2006/07/12(水) 23:44:44ID:???
>>469
それじゃ同じ答えしか返ってこない。
system使えとか、``使えとか、qx() しろとか。
systemの戻り値を調べるか、$! を見て。
0473nobodyさん2006/07/12(水) 23:46:15ID:3OAigznj
''入れたら自己解決しました。
本当にありがとうございました。
0474nobodyさん2006/07/12(水) 23:53:16ID:???
>>469
>ちょっと質問変えてみます
>Perlでシェルスクリプト実行するにはどうしたらいいでしょうか?
まあ、同じ答えになるんだけどもちょっとだけ詳しく。
「/PATH/hoge.sh を引数 piyo つきで実行するなら」
system "sh /PATH/hoge.sh piyo" ;
「STDOUT を perl の変数に直接入れたいなら」
open EXE, "sh /PATH/hoge.sh piyo|" ;
@data = <EXE> ;
「STDERR とか細かなところまで制御したいなら」
perldoc IPC::Open3あたり
0475nobodyさん2006/07/13(木) 00:17:16ID:???
>>469
Inline::Bash を書いて CPAN に上げてください。
応援しています。
0476nobodyさん2006/07/13(木) 00:23:07ID:???
>>465
Perl は UNIX 上の仕事をやっつけるために生まれ、UNIX 系のシステムを中心に普及したから。
でも主流じゃないことを気に病むことはないよ。まずは悩む代わりに、その時間を使ってコードを書くんだ。
0477nobodyさん2006/07/13(木) 00:26:45ID:???
>469
`
0478nobodyさん2006/07/13(木) 00:32:23ID:???
>>453
>探す文字がパターンマッチを必要としないならindexの方が激速。

あんま誤解の生じること言わないほうがいいw
0479nobodyさん2006/07/13(木) 00:38:17ID:???
>>478
一般に正しいと思うけど。
(最適化のかかる)オートマトン作らなくて良いパターンでなければ、
indexの方が遥かに安価で速いだろう。
04804692006/07/13(木) 00:39:17ID:???
うーん。できない・・・
0481nobodyさん2006/07/13(木) 00:45:41ID:???
>>469 は管理者権限の意味を理解しているのか小一時間(ry
0482nobodyさん2006/07/13(木) 00:48:22ID:???
ここWebProg板だから、CGIでuseraddしようとしてたりして…。
0483nobodyさん2006/07/13(木) 00:48:54ID:???
>>479
正しくないw
ベンチとってみればわかるけど

A1 $_ =~ /hoge/
A2 index($_, 'hoge')

my $word = 'hoge';
B1 $_ =~ /$word/
B2 index($_, $word)

A1 A2 はほぼ同じ速さで、
B1 は B2 より速い。

index($_, $word[1]) or index($_, $word[1]) ・・・
より
/$word[0]/ or $word[1] ・・・
のが速い。

$_ が 'aaaaaaa......' で $word が 'baaaaaaaaaaaa' とかいう特殊な場合は考えないでね。
04844692006/07/13(木) 00:48:56ID:???
root権限でcgiを実行ってことですか?
0485nobodyさん2006/07/13(木) 00:50:07ID:???
>>483 訂正
× /$word[0]/ or $word[1] ・・・
○ /$word[0]/ or /$word[1]/ ・・・
0486nobodyさん2006/07/13(木) 00:50:10ID:???
>>479
日本語の問題だと思うけど。
「探す文字がパターンマッチを必要としないなら(最適化がかかるので)indexの方が激速なんてことはない。」
04874582006/07/13(木) 00:52:59ID:aY2uz4D9
>>464
レスありがとうございます。
もう少し具体的に質問します。

まずparent.cgiがあります。ここやってることはhtmlテンプレートを使ったchild.htmlファイルを読み込んで表示させるだけです。つまり
$template = HTML::TEMPLATE->new(
  filename => 'child.html',
);
print $template->output;
のような感じです。


このchild.htmlでは
<!-- TMPL_INCLUDE NAME="hoge.html" -->
のようにhtmlファイルを読み込んでいます。

しかし今回このhoge.htmlの代わりにhoge.cgiを使いたいのです。つまり静的なhtmlファイルではなくcgiを使ってここに表示される内容を動的に変化させたいわけです。これをするのにいい方法ありますでしょうか?
0488nobodyさん2006/07/13(木) 01:04:37ID:???
>>487
静的なhtmlをincludeするんじゃなくて、そこで普通にテンプレートを使えば
実質お望みの事ができると思うんだけど…。
0489nobodyさん2006/07/13(木) 01:05:37ID:???
>>487
いろいろ方法はあるだろうけど、全く別の CGI を呼ぶ 「いい方法」 というなら SSI が 「いい方法」 だと思うぞ。
0490nobodyさん2006/07/13(木) 01:06:25ID:???
実はそこに入れたいのは カウンター とかいう話じゃねえのかなw
0491nobodyさん2006/07/13(木) 01:17:32ID:???
質問
パーミッション777のディレクトリだとmkdirできるのですが
755だとできません。777だとセキュリティ的に問題ですよね?
755のディレクトリ直下に新規ディレクトリを作成するにはどうしたらいいでしょうか?
0492nobodyさん2006/07/13(木) 01:29:08ID:???
>>484
よく分かってないなら、そういうプログラムは組まない方がいい。
0493nobodyさん2006/07/13(木) 01:29:35ID:???
>>491
じゃー、chmod で 777 にしてから mkdir して 755 に戻せば?
0494nobodyさん2006/07/13(木) 01:43:02ID:???
>>493
777のディレクトリだとchmodできましたが
755のディレクトリだとchmodできませんでした・・・
04954872006/07/13(木) 02:29:43ID:aY2uz4D9
>>487
知識不足で申し訳ないです。普通にテンプレートを使うとはどういうことでしょう?テンプレートでcgiを実行するようなものがあるんですか?

>> 489
SSIで試してみました。parent.cgiから読み取るのをchild.shtmlにしてその中で<!--#exec cmd="perl hoge.cgi" -->として実行してみました。

結果普通にchild.shtmlを見ると実行が確認できたのですが、parent.cgiの中でshtmlを読み込んでしまうとSSIが実行されないようでダメでした。

>>490
カウンターではありませんw
0496nobodyさん2006/07/13(木) 02:50:05ID:???
>>495
テンプレート使ってるってことは、そもそもCGIで動いてるんでしょ。
その場で動的なページ作ればいいだけでは。

テンプレートで静的なhtmlを読み込んで、
さらにそこからCGI叩いて動的なページを、、、なんて考える前に。
04974952006/07/13(木) 03:13:47ID:aY2uz4D9
>>496
レスありがとうございます。

しかしそのテンプレートのhtmlの"ある部分"にCGIの結果を入れたいんですよ。そこはスタイルシート等で位置が厳密に決まっているのでその部分だけ元のparent.cgiでhoge.cgiを呼び出してってのは難しいんじゃないかと思ってます。
0498nobodyさん2006/07/13(木) 03:25:44ID:???
じゃあもう iframe でいいじゃん。それかAjax
0499nobodyさん2006/07/13(木) 06:06:02ID:???
>>483
言いたい事はわかるが、
それはパターンマッチを必要とする条件じゃないのか?

ただの文字列を探すならindexしかないだろ。
0500nobodyさん2006/07/13(木) 06:14:58ID:???
Cとかでは確かにindexは激速だが、Perlはもしかしたらindexが正規表現ライブラリの
皮をかぶってるかもしれないから、ソース見るかベンチ取るかしてみないと(ry
0501nobodyさんNGNG
昔indexの方が速かった覚えがあるので
ふつーに簡単なベンチ取ったら
indexの方が2倍 速かったんですけど
当然っちゃー当然の結果やね
0502nobodyさん2006/07/13(木) 06:32:39ID:???
こういう結果もあるぞ。

http://x68000.q-e-d.net/~68user/webcgi/search-1.html
05034572006/07/13(木) 07:33:25ID:???
気分良く寝てたので話題に乗りおくれた。
>>502
横レスだけどリンク先を良くよんだら?
search-2.cgi がせめて and 検索だったらいいんだけどリンク先は
アンフェアな比較だよ。(まあ、そういう目的で作ったんんじゃない
だろうけど)
以下は寝起きで確認したベンチマークのソース。
#!/usr/bin/env perl -w
#use strict ;
use Benchmark ;
my $str1 = ( 'a' x 30 ) . 'hoge' . ( 'a' x 10 ) ;
my $str2 = ( 'a' x 30 ) . ' hoge ' . ( 'a' x 10 ) ;
sub cont1(){ $str1 =~ /hoge/ }
sub cont2(){ $str2 =~ /hoge/ }
sub test_index1(){ index $str1, 'hoge' }
sub test_index2(){ index $str2, 'hoge' }
timethese 500000, { o0 => 'cont1' , o1 => 'cont2' , o2 => 'test_index1' , o3 => 'test_index2' } ;
================
Benchmark: timing 500000 iterations of o0, o1, o2, o3...
o0: 1 wallclock secs ( 1.66 usr + 0.01 sys = 1.67 CPU) @ 299401.20/s (n=500000)
o1: 2 wallclock secs ( 1.66 usr + 0.02 sys = 1.68 CPU) @ 297619.05/s (n=500000)
o2: 1 wallclock secs ( 1.43 usr + 0.01 sys = 1.44 CPU) @ 347222.22/s (n=500000)
o3: 1 wallclock secs ( 1.43 usr + 0.01 sys = 1.44 CPU) @ 347222.22/s (n=500000)
0504nobodyさん2006/07/13(木) 07:46:36ID:???
search-3.pl って eval でモロ高速化してんじゃん…
search-2 が and 検索であろうとなんであろうと、単純な index と正規表現
の速度比較のソースにはならんな。
0505nobodyさん2006/07/13(木) 13:17:19ID:???
>>500
>Perlはもしかしたらindexが正規表現ライブラリの
>皮をかぶってるかもしれないから
それは普通に考えてありえない…。
0506nobodyさん2006/07/13(木) 15:37:15ID:???
>>503

>>483 でやってみて。
検索文字が文字列か変数かどうかで結果が変わるんだよ。
0507nobodyさん2006/07/13(木) 16:04:15ID:???
>>506
>>503 と同じようなのを書いてベンチ取った。
何度かやってみたが、変数に入れてもindexの方が速かった。

#!/usr/bin/perl
use Benchmark;

my $str1 = ('a' x 30) . 'hoge' . ('a' x 10);
my $str2 = ('a' x 30) . ' hoge ' . ('a' x 10);

sub test_reg1 { my $hoge = 'hoge'; $str1 =~ /$hoge/; }
sub test_reg2 { my $hoge = 'hoge'; $str2 =~ /$hoge/; }
sub test_index1 { my $hoge = 'hoge'; index($str1, $hoge); }
sub test_index2 { my $hoge = 'hoge'; index($str2, $hoge); }

timethese 500000, {
 reg1 => 'test_reg1',
 reg2 => 'test_reg2',
 idx1 => 'test_index1',
 idx2 => 'test_index2',
};

idx1: 1 wallclock secs ( 0.83 usr + 0.00 sys = 0.83 CPU) @ 602409.64/s (n=500000)
idx2: 0 wallclock secs ( 0.83 usr + 0.00 sys = 0.83 CPU) @ 602409.64/s (n=500000)
reg1: 1 wallclock secs ( 1.00 usr + 0.00 sys = 1.00 CPU) @ 500000.00/s (n=500000)
reg2: 0 wallclock secs ( 1.00 usr + 0.00 sys = 1.00 CPU) @ 500000.00/s (n=500000)
0508nobodyさん2006/07/13(木) 16:11:59ID:???
>>506
ちなみに >>483 みたいに orで繋ぐのもやってみたけど、
やっぱり indexの方が速かった。
0509nobodyさん2006/07/13(木) 16:38:50ID:???
>>508
あー、ほんとだ。

でもね、検索対象のサイズを大きくするにしたがって逆転していくみたい。

my $str1 = ('a' x 10000) . 'hoge' . ('a' x 1000);
my $str2 = ('a' x 10000) . 'hage' . ('a' x 1000);

とかでやってみておくれ。 これは 11k だけど、うちの環境では 1k あたりから差がではじめた。
0510nobodyさん2006/07/13(木) 17:11:02ID:???
>>509
そりゃ長くなれば BM法にアルゴリズム変えるからね。正規表現の方は。
0511nobodyさん2006/07/13(木) 17:29:16ID:???
結局長さとか対象文字列に依存して違う結果が出るので
気になる人はよく考えるなり実験するなりして選択しろと
いうことか。
0512nobodyさん2006/07/13(木) 17:33:49ID:???
ただ正規表現でいつまでもオプショナルな文字列が無い
(オートマトン作らなくて良い)なんて事は無いし。
0513nobodyさん2006/07/13(木) 19:41:52ID:???
index使わないコーディングスタイルはKENTのせい。
■ このスレッドは過去ログ倉庫に格納されています