Perlコーディング初心者質問スレ Part 47
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
2006/03/01(水) 15:39:31ID:???【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。
過去ログやお勧めサイトは >>2-10
0357nobodyさん
2006/03/28(火) 22:36:22ID:???0358nobodyさん
2006/03/28(火) 23:34:57ID:???0359nobodyさん
2006/03/29(水) 05:38:58ID:???括弧を書いてるならまだホントの旨みを味わってない。
Perlの真骨頂は如何に少ないタイプでコーディングするかにある。
0361nobodyさん
2006/03/29(水) 07:17:11ID:???ふつー print join("\n", @array);
0363nobodyさん
2006/03/29(水) 07:59:38ID:???0365nobodyさん
2006/03/29(水) 11:08:43ID:???つ\n
0366nobodyさん
2006/03/29(水) 12:10:29ID:???0367nobodyさん
2006/03/29(水) 13:40:08ID:???0368nobodyさん
2006/03/29(水) 13:52:08ID:???0369nobodyさん
2006/03/29(水) 13:53:27ID:???0370nobodyさん
2006/03/29(水) 14:09:04ID:???本気でそう思ってるのか?考え方の矯正をお薦めする。
遅いし、printを繰り返すし、無駄な変数使うし、良いとこなしだ。
レス返されてムキになってる訳じゃなくて、それが素の考え方ならある意味凄い。
0371nobodyさん
2006/03/29(水) 14:11:52ID:???うちなんか16倍も差が出たよ。
こんだけ早いならjoin使おうかな・・・
ちなみに下の2つでは微妙にmapのが早かった。
print "$_\n" for @array;
print map "$_\n", @arrray;
0372nobodyさん
2006/03/29(水) 14:23:46ID:???じゃあ、最後の "\n" がはみごになるのは気持ち悪くないの?
これが自然と思うのが Perl 流だというのなら仕方ないけど、
俺はものすごく気持ち悪くて仕方がない。
0373370
2006/03/29(水) 14:30:31ID:???確かに気持ち悪い。でも、組み込み関数を使えるところは使うのが基本だし、
その一つとさっき挙げた数点を比べたら、その一つの点の為に他を犠牲にすることは出来ない。
0374nobodyさん
2006/03/29(水) 14:40:23ID:???0375nobodyさん
2006/03/29(水) 14:41:08ID:???俺なら、例え 16倍も速度差が出たとしても、
本当にそこがボトルネックで困っているようなケースでないのであれば、
読み下せて意味が明確でわかりやすい方を取るけどな。
0376nobodyさん
2006/03/29(水) 14:46:11ID:???if ($regist_key) {
$cd = $in{'code'};
$cd =~ s/\D//g;
if ( $cd =~ m/^\d{5}$/ ) {
$les = $addr;
$les =~ s/\D//g;
$les =~ /^(\d{5})(\d+)/;
$les = $1;
$cod = $cd + $les;
$cod =~ /^(\d{4})(\d+)/;
$cod = $1;
}
if ($cod ne $in{'regikey'}) { $err .= "投稿コードが不正です。<br>"; }
}
0377376
2006/03/29(水) 14:47:57ID:???# 投稿コード作成
sub key_image {
@num = (0 .. 9);
srand;
foreach (1 .. 5) {
$regikey .= $num[int(rand(@num))];
}
$les = $addr;
$les =~ s/\D//g;
$les =~ /^(\d{5})(\d+)/;
$les = $1;
$nu = $regikey + $les;
$nu =~ /^(\d{4})(\d+)/;
$nu = $1;
# テキストコード表示
print "<input type=text size=5 value=$nu>\n";
}
この中に使われない物は入ってます?
0378nobodyさん
2006/03/29(水) 14:51:18ID:???2,a,梨
3,b,西瓜
4,b,イチゴ
5,a,桃
のようなtest.txtというファイルを元に、
2つめの項目がaのを抜き出し表示する為に、
open(IN,"test.txt") || &error("Open Error: $logfile");
while (<IN>) {
($no,$type,$name) = split(/,/);
if ($type eq 'a') {
print "$name<br>\n";
}
}
close(IN);
とwhileで全行回すしかないのでしょうか?
0379nobodyさん
2006/03/29(水) 16:36:14ID:???正規表現やgrep等でもOK。
my $in = join( '', <> );
my @result = $in =~ /^\d+,a,.*$/gm;
my @in = <>;
my @result = grep { /^\d+,a,.*$/ } @in;
文法チェックもしてないけど、こんな感じで。
1つめの1行目は、my $in; { undef $/; $in = <>; }
とかの方が丁寧だけど。
0380nobodyさん
2006/03/29(水) 16:38:19ID:???あ、1個目
- my @result = $in =~ /^\d+,a,.*$/gm;
+ my @result = $in =~ /^(\d+,a,.*)$/gm;
だった。
他にも間違ってるとこあるかも。
0381nobodyさん
2006/03/29(水) 17:20:47ID:???0382nobodyさん
2006/03/29(水) 18:46:24ID:???0383nobodyさん
2006/03/29(水) 19:24:01ID:???0384nobodyさん
2006/03/29(水) 19:54:55ID:???100万回でチェック
push (@array, rand) for (1..100000);
print "$_\n" foreach @array; ### 0.91 CPU [3]
print join "\n", @array; ### 0.54 CPU [2]
local $, = "\n"; print @array; ### 5.11 CPU [5]
print map "$_\n", @arrray; ### 0.39 CPU [1]
print $_, "\n" foreach @array; ### 0.93 CPU [4]
local $,が目立って遅かった…
0388nobodyさん
2006/03/29(水) 22:08:29ID:???push @array, rand for 1..100000;
timethese(100,
{
q{print STDERR "$_\n" foreach @array} => sub {print STDERR "$_\n" foreach @array},
q{print STDERR join "\n", @array} => sub {print STDERR join "\n", @array},
q{local $, = "\n"; print STDERR @array} => sub {local $, = "\n"; print STDERR @array},
q{print STDERR map "$_\n", @array} => sub {print STDERR map "$_\n", @array},
q{print STDERR $_, "\n" foreach @array} => sub {print STDERR $_, "\n" foreach @array},
});
print STDERR join "\n", @array: 2 wallclock secs ( 1.84 usr + 0.03 sys = 1.88 CPU) @ 53.33/s (n=100)
print STDERR "$_\n" foreach @array: 16 wallclock secs (11.66 usr + 3.94 sys = 15.59 CPU) @ 6.41/s (n=100)
print STDERR map "$_\n", @array: 22 wallclock secs (19.12 usr + 3.47 sys = 22.59 CPU) @ 4.43/s (n=100)
local $, = "\n"; print STDERR @array: 23 wallclock secs (16.55 usr + 6.75 sys = 23.30 CPU) @ 4.29/s (n=100)
print STDERR $_, "\n" foreach @array: 25 wallclock secs (17.66 usr + 6.83 sys = 24.49 CPU) @ 4.08/s (n=100)
0389388
2006/03/29(水) 22:12:56ID:???0390nobodyさん
2006/03/29(水) 22:23:16ID:???わからにゃい。。
0391nobodyさん
2006/03/29(水) 23:31:28ID:???# mapブロック版と$"使用版を追加してます。
# 出力結果が同じになるようjoinに,"\n"追加してます。
print STDERR join("\n", @array),"\n": 2 wallclock secs ( 1.47 usr + 0.01 sys = 1.48 CPU) @ 67.57/s (n=100)
local $" = "\n"; print STDERR "@array\n": 2 wallclock secs ( 1.75 usr + 0.01 sys = 1.76 CPU) @ 56.82/s (n=100)
print STDERR "$_\n" foreach @array: 10 wallclock secs ( 7.57 usr + 2.44 sys = 10.01 CPU) @ 9.99/s (n=100)
print STDERR map "$_\n", @array: 13 wallclock secs (10.34 usr + 2.56 sys = 12.90 CPU) @ 7.75/s (n=100)
print STDERR map {"$_\n"} @array: 13 wallclock secs (10.47 usr + 2.54 sys = 13.01 CPU) @ 7.69/s (n=100)
local $, = "\n"; print STDERR @array: 14 wallclock secs ( 8.49 usr + 5.18 sys = 13.67 CPU) @ 7.32/s (n=100)
print STDERR $_, "\n" foreach @array: 15 wallclock secs (10.38 usr + 5.03 sys = 15.41 CPU) @ 6.49/s (n=100)
最初はlocalのせいで遅いのかとも思ったけど違うみたい。
内部で、$"はjoin、$,はmapあたりを使ってるなじゃないかと。
0392nobodyさん
2006/03/29(水) 23:58:21ID:???これって省略無しで書くとどんな感じ?
他はなんとなく処理がわかるけど、これだけ判らない。
解説プリーズ。
0393356
2006/03/29(水) 23:59:36ID:???0394352
2006/03/30(木) 00:05:57ID:???倒置っていうか、>>358が言うみたいな後置きの事です。
意味不明な言葉を補完してくれた人感謝。
やっぱ覚えておくとよさそうだなぁ。
ただ、書き方が()要るかとか$_とか使い出したりでちょっと面倒なんだよね。
解説してくれてるところが妙に見つからないし、習うより覚えろって事かな。
0395356
2006/03/30(木) 00:12:08ID:???「Effective Perl」オヌヌメ。最近買ったんだけど、例えばforeachとmapとgrepの
明確な使い分けとか、そんなレベルでPerlのセンスを磨いてくれる良書だとオモタ。
後置きについても書いてあったかは忘れたけど、例文にはバンバン登場するので
非常に参考になる。
>>359
その通りだね。括弧書いたのは後でシモタとオモタよ。
0396nobodyさん
2006/03/30(木) 00:14:55ID:???print $_, "\n" foreach @array; ### 0.93 CPU [4]
print STDERR "$_\n" foreach @array: 16 wallclock secs (11.66 usr + 3.94 sys = 15.59 CPU) @ 6.41/s (n=100)
print STDERR $_, "\n" foreach @array: 25 wallclock secs (17.66 usr + 6.83 sys = 24.49 CPU) @ 4.08/s (n=100)
連結って思ったより処理負荷大きいのかな。
気をつけようっと。
0397nobodyさん
2006/03/30(木) 00:41:13ID:???Benchmark: timing 10000 iterations of $a .= "a" , $a = $a . "a"...
$a .= "a" : 0 wallclock secs ( 0.17 usr + 0.00 sys = 0.17 CPU) @ 5882.35/s (n=1000)
$a = $a . "a": 85 wallclock secs (84.41 usr + 0.01 sys = 84.42 CPU) @ 11.85/s (n=1000)
うへぇ
0400nobodyさん
2006/03/30(木) 00:51:51ID:???0401nobodyさん
2006/03/30(木) 01:07:54ID:???print STDERR だとバッファリングされずに必ず write(2) するから、
print STDOUT に比べて圧倒的に速度的に不利になると思うんだけど。
0402nobodyさん
2006/03/30(木) 01:33:47ID:???0405nobodyさん
2006/03/30(木) 01:59:04ID:???そりゃある文ではSTDERRつかって、ある文ではSTDOUT使ってたらベンチに偏りが出るけどさ・・・
条件が同じなら出力先はファイルでもなんでもいいんだよ
0406nobodyさん
2006/03/30(木) 02:13:52ID:???他の処理のせいで処理自体の差は100/sと50/sの差なのに、
10/sと9/sって差が出てしまったら大差なさそうに感じてしまうし。
0407nobodyさん
2006/03/30(木) 02:31:39ID:???いやいや、だから、 >>389 が言ってるように、
print (というか write(2)) の回数が多い方が極端に不利になるじゃん、という話。
0410nobodyさん
2006/03/30(木) 03:21:17ID:???煽ってるつもりなのだろうか。
0411nobodyさん
2006/03/30(木) 05:10:05ID:???ってのが、ラクダ本あたりにもよく出てくるよね。
0412nobodyさん
2006/03/30(木) 06:41:01ID:???joinの方が圧倒的に速いんだろうか?
0415nobodyさん
2006/03/30(木) 09:33:15ID:???0416407
2006/03/30(木) 10:45:36ID:???print FILE join("\n", @array),"\n": 10 wallclock secs ( 8.07 usr + 2.05 sys = 10.12 CPU) @ 9.88/s (n=100)
local $" = "\n"; print FILE "@array\n": 13 wallclock secs (10.10 usr + 2.20 sys = 12.30 CPU) @ 8.13/s (n=100)
print FILE "$_\n" foreach @array: 19 wallclock secs (18.08 usr + 1.20 sys = 19.28 CPU) @ 5.19/s (n=100)
print FILE map "$_\n", @array: 30 wallclock secs (27.93 usr + 1.07 sys = 29.00 CPU) @ 3.45/s (n=100)
print FILE map {"$_\n"} @array: 29 wallclock secs (27.60 usr + 1.23 sys = 28.84 CPU) @ 3.47/s (n=100)
local $, = "\n"; print FILE @array: 13 wallclock secs (10.70 usr + 1.18 sys = 11.88 CPU) @ 8.42/s (n=100)
print FILE $_, "\n" foreach @array: 19 wallclock secs (16.84 usr + 1.16 sys = 18.00 CPU) @ 5.56/s (n=100)
map はどうあがいても遅そうですが、他は join との差がかなり縮まってると思います。
0417nobodyさん
2006/03/30(木) 11:19:01ID:???0418407
2006/03/30(木) 11:54:18ID:???まあベンチマークってそういうもんなんじゃないでしょうか。
机上だけでやっちゃうってのも問題ですが、
ベンチマークを鵜呑みにするのも問題だと思います。
ベンチマークも一つの目安に過ぎないんだと思います。
0419nobodyさん
2006/03/30(木) 13:55:21ID:???この板のレベル的に
0422nobodyさん
2006/03/30(木) 14:52:07ID:???print map {"$_\n"} @array 13.8/s -- -1% -44% -52% -69% -76% -80%
print map "$_\n", @array 14.0/s 1% -- -43% -51% -69% -75% -79%
print "$_\n" foreach @array 24.4/s 77% 75% -- -15% -46% -57% -64%
print $_, "\n" foreach @array 28.7/s 109% 106% 18% -- -36% -49% -57%
local $, = "\n"; print @array 45.0/s 227% 223% 85% 57% -- -20% -33%
local $" = "\n"; print "@array\n" 56.5/s 310% 305% 132% 97% 25% -- -16%
print join("\n", @array),"\n" 67.6/s 391% 384% 177% 135% 50% 20% --
まぁ、自分はこの差が問題になるよなコードを書くことはないと思うけど。
0424nobodyさん
2006/03/30(木) 15:31:44ID:???むしろどんどんやってくれ。
0425nobodyさん
2006/03/30(木) 15:56:27ID:???書き方によってスピードに差が出るってのをベンチマークとって分かればいいんだから、
ファイルに書き出した結果もベンチ結果の1つでしょ?
またSTDERRに書き出してたベンチも結果の1つ
君がそれ以上に何が知りたいかのかわからんよ
0427nobodyさん
2006/03/30(木) 19:01:15ID:+BI4fyV2ひとつひとつを変換するのではなく、一度に変換する良い方法ありませんか?
0428nobodyさん
2006/03/30(木) 19:23:03ID:???一度に変換する方法など、Perlでなくてもありません。
0429nobodyさん
2006/03/30(木) 23:12:22ID:???それもわずかな差じゃなくて数倍以上。
一体中で何が起きてるんだ…
子ネタ
ttp://itpro.nikkeibp.co.jp/article/NEWS/20060330/233820/
0430nobodyさん
2006/03/31(金) 00:19:33ID:???あなた自分の解釈の間違いに意固地になって必死すぎ
0432nobodyさん
2006/03/31(金) 00:34:36ID:???0435nobodyさん
2006/03/31(金) 01:47:32ID:???Σ
春休みかorz
0436nobodyさん
2006/03/31(金) 01:58:45ID:???変なのが絡みだすとこういう事に。
この板住人は煽り耐性低いというか、言い返さずに入られない人多いよな。
0437nobodyさん
2006/03/31(金) 02:11:22ID:???0438nobodyさん
2006/03/31(金) 02:47:50ID:???この空気じゃなかなか質問がしづらいという悪循環。
0439nobodyさん
2006/03/31(金) 13:33:21ID:MWW8UoCrその一行を教えてください><
0441nobodyさん
2006/03/31(金) 15:28:24ID:???特に何も省略されてないと思われ。
print 演算子の出力フィールドセパレータ (デフォルトは空文字列) を「改行」にし、
@array を print する。
って感じで。
0442nobodyさん
2006/03/31(金) 16:06:55ID:???なんとなく把握できた。
解説感謝。
0444nobodyさん
2006/03/31(金) 18:52:18ID:???たとえば
<a href=read.cgi?bbs=$bbs&key=$key&ls=$lslimit&mode=i accesskey=3>?新</a>
とかは携帯から見れる新って書いてあるリンクをおすと#63881に書いてあるコマンドを実行するってことですか?
リンクを押すと新しいレス10件を表示させるようにしたいのですが、そのコマンドがどこに書いてあるのかわからなくて・・。
0445nobodyさん
2006/03/31(金) 19:49:56ID:???#63〜ってのはエモジのことみたいですね。
0446nobodyさん
2006/03/32(土) 01:29:26ID:???これがわからんかったんで調べた・・・ (知ってる人にはどうでもいいことだろうけど、分からない人も居るだろうし・・・)
$, 自体が特殊変数で、print 関数で表示する際にセパレータとして挿入される値
>>392 の例だと、「配列の要素間に \n を入れる」 という意味
なるほど勉強になりました。
0447nobodyさん
2006/03/32(土) 01:31:27ID:???初心者なので思ったりする。
0448nobodyさん
2006/03/32(土) 01:37:06ID:???0449nobodyさん
2006/03/32(土) 02:16:23ID:???ありがとう。
0450nobodyさん
2006/03/32(土) 08:17:31ID:???勉強になります
0451nobodyさん
2006/03/32(土) 09:15:53ID:???>>422
目的のアルゴリズム部だけの速度を求めたいのなら、print は一切省いて
join("\n", @array),"\n";
local $" = "\n"; "@array\n";
"$_\n" foreach @array;
map "$_\n", @array;
map {"$_\n"} @array;
local $, = "\n"; @array;
$_, "\n" foreach @array;
とかでいいと思う。デバイスに出力するのが遅いだけでなく、print 関数の使用自体が
遅い可能性もあるし(C言語とかだとそう)。
まぁ、これだと $, を使用したときの正確な値が求められないが、内部的に $, は
そんなにコストがかかっていなさそう。
おそらく内部では、$, ||= ''; (←実際にはCとかで)とでもやって条件分岐なしで処理してそうだし。
実際にベンチをとって確認するのは大切なことだけどね。
0452nitraid
2006/03/32(土) 14:06:31ID:G839mIFtThe Roomさんの振り分けCGIを使ってみたのですが、最近の携帯ではPCページにアクセスしてしまうようで困っております。
みなさんよろしくお願いします。
0453nobodyさん
2006/03/32(土) 14:14:34ID:???0454nitraid
2006/03/32(土) 14:40:58ID:G839mIFtDoCoMo、au、vodafoneどれなのかを判別して振り分けたいのですが、各端末情報を書かなければいけませんか?
よろしくお願いします。
0455nobodyさん
2006/03/32(土) 14:53:28ID:???■ このスレッドは過去ログ倉庫に格納されています