★負荷軽減対策委員会(Perl、PHP)★
サーバ上にPerlやPHPを置く場合、何よりも重視しなければ ならないのはサーバへの「負荷」。 負荷の高いCGIの使用は削除対象となるのが目に見えてます。 負荷を軽減させるにはどうすればいいか? どういう書き方をすればいいか? そんな委員会を開設しました。 Perlで3MくらいのCSVを読み書きするのって、 かなりの負荷? あと、ここのみなさんは、どうして負荷について知識があるんでしょうか? 経験上? >>291 一回しかやらないのなら 大した負荷にならないが BBSのログとかだったら負担になるかもね >>291 DBM使え。簡単だぜ。 郵便番号ファイル(郵政省--いま何たっけ--の)で速度5倍だぜ。 http://www.ichikoro.com/webp/bk/00060.html のベンチマーク。 あれ、2Mくらいじゃなかったっけ? >>288 そうそう。よほど非常識なことをしなければ、スクリプト言語で効率を考えるのはナンセンス。 >>296 >>295 にあるように効率はいつも考えるべき。 >>297 そうだね。コードの一つ一つで効率を考えることによって、 全体としてそうとうの負荷軽減になる。例えば、 http://www.mikeneko.ne.jp/ ~lab/perl/numerical_transform/#h4を ベンチマークで検索してみれ。 >>292 そうかー、ちょっと反省。 ところでどなたか、↓の質問答えてほしいです。。。 >あと、ここのみなさんは、どうして負荷について知識があるんでしょうか? >経験上? あと、負荷軽減について詳しい本(の一部とか雑誌でも)ないでしょうか? 負荷がどうとかと言う人ほど、use strictしたままリリースしそう。 use strict すると負荷がかかるんですか? >>302 検査する時間が増えるだろ、アクセスごとに検査させるのか。 Cでいえばassert有効にしたままリリースってのに似ているな。 わざとそうしている人もいるみたいだけど・・・ 負荷を測るのってどうすればいいの。 自分のPCで動かしてもよーわからん。 メモリについて質問させて下さい。 例えば $x="abc"; の後、 $x=""; という記述なしに $x="def"; とした場合、メモリは、 abcの○○○分と、defの○○○分の ○○○○○○分が確保されてしまいますか? $x="abc"; $x=""; $x="def"; にすれば メモリ確保は○○○だけになると思うのですが。 >>307 たぶん・・・ 変数へ上書きしたら、ちゃんと初期化(開放)してから、 代入してくれると思ふ。 >>308 そうですか。 では$x="";は無駄ですね。 ありがとうございます。 Perlは最初に確保したメモリ空間を開放しません。 たとえ、ゼロに初期化しても。undefなら別。 http://www.mikeneko.ne.jp/ ~lab/perl/tuning/ >>310 すんまそん。 メモリ確保を解放するかしないかは分かります。 メモリ確保は○○○分で済むのか、○○○○○○分確保してしまうのかを聞きたいのです。 詳しく知りたかったら、Perlのソースを読むしかないと思うけど。 >>315 >>310 の記述を見ると、3バイト分しか確保しないように思えたけども。 apacheのログ2,3日分。約4M。PHP。極貧マシン。 while & fgets & copy -> 処理50秒前後 メモリ使用4M前後 CPU100% file & foreach(or list&each) & copy -> 処理60秒前後 メモリ使用15M前後 CPU100% fread & copy -> 処理0.5秒前後 メモリ使用4M前後 CMP100% ━―━―━―━―━―━―━―━―━[JR山崎駅(^^)]━―━―━―━―━―━―━―━―━― ファイルをコピーする時って open(IN,"Src.txt"); #コピー元ファイル Src.txt をオープン while(<IN>){ # 一行毎の読み込みループで変数$Bufに読み込む $Buf .= $_;} close(IN); #ハンドル IN が不要になったので閉じる ◇デソースに書き出す open(OUT,"> Dst.txt"); #コピー先ファイル Dst.txt をオープン print OUT,$Buf; #ソースの内容($Buf)を書き出す close(OUT); のように一行ずつ読み込んでく場合と @line=<IN>; みたいにいっきに配列に入れてしまうのはどちらが処理としてはいいのでしょうか? >>324 open IN, '<' . $src or die; open OUT, '>' . $dst or die; my $buffer_size = 1024; # 適宜調整 my $buffer; print OUT $buffer while read IN, $buffer, $buffer_size; close OUT; close IN; >>325 さん それが最適なのですか。 勉強になります…。 サイズ1024は何を意味しているのだろう… >>326 1024 byte は 1 kbyte だろ? コンピュータの基礎じゃねえか。 ま、俺だったらFile::Copyモジュールを使うかも。 バグがあるかも知れないソース書くより楽だし。 my $buffer_size = 1024; # 適宜調整 すいません。 これを記述することで何が得なのかを知りたいのでした。 >>329 実行エンジンにもよるんだけども、メモリを確保する場合、8byte単位とかそういうのが多いから (アライメント)。 Perlだとどうだか?って気もするけども。 >>329 微妙に意味がわからんな…… 推測をして回答してみる。 1.$buffer_sizeを設定することで、何バイトずつコピーするのかの設定が可能になる。 この数値を小さくすると、コピー回数が増えるが、メモリーへの負担は減る。 この数値を逆にすると、その逆。 サーバーの具合を見て適宜調整することができる。 2.わざわざ変数を一つ設定することの意味は、変数の名前をわかりやすくすることで、 その変数が何に使われているのかをわかりやすくする。 「昨日の自分は他人」の言葉どおり、後から見た時になんでその数値にしたのか等が判断しやすくなる。 何が聞きたいんだろう…… 3. 設定(定数)と実働部分はできるだけ分離する。 >>324 のコード片がスクリプトのどこに埋もれていても、 変数 $buffer_size としてスクリプトの頭の方で定義しておけば 簡単にバッファサイズを変更できる。定数で埋め込んでしまうと 変更したい時にいちいち探し回る事になる。 Perlは最適化とかしないのかな? @buf = <IN> のほうが早かったりして。 open(IN, $src); open(OUT, '>'.$dst); print OUT while(<IN>); close(IN); close(OUT); こう書くかも。 readで読み出すバイト数は多い方が速いと思う。当然だけど。 ただ多過ぎるとそれはそれでメモリくったり。 >>335-336 ベンチ取れば分かる事だが、@buf = <IN> はメモリを一気に 確保する = System CPU time を食う。行入力演算子による 取得は「行末」を探す = 可変長入力なので潜在的に read より遅い処理。もちろん扱うデータのフォーマット & 量次第 だけどね。 どうしても行入力演算子でやりたければ $/ = \1024; while (<IN>) { ... } で 1024 byte 単位で読めるけど、素直に read 使った方が 速かったかと。 たしかにそうですね。 改行コードを探しながら進むので遅いと。 ∧_∧ ピュ.ー ( ^^ ) <これからも僕を応援して下さいね(^^)。 =〔~∪ ̄ ̄〕 = ◎――◎ 山崎渉 ファイルの書き込みを追記にしたばあいの負荷ってどうなるんですか。 たとえば書き込むものは同じとして、 追記先のファイルが1行のときと1000行のときでは CPUメモリ負荷はどうなるんでしょう。 追加するだけだから大して変わらないかなと思ったんですけど。 $kazu=(((($my_tech-int(rand($my_tech/4)))*$job_dmg[$job])*$tarou)/$mstamina)*$stamina; このように一気に計算させるのと、 いくつもに分けて計算させていくのでは 負荷は変わるのでしょうかね? 変わるのならどちらが軽いと思いますか? >>341 追記の場合、元のファイルの大きさはほぼ影響しない。 Cをやっている人間ならわかる(はず)だが、 追記と言うのは、ハードディスク上のファイルの終端を探し出して、 そこから新たなデータを埋めて行き、最後にファイルの大きさを示す数値を変更する作業だ。 従って、ファイルの終端を探し出す作業だけが、ベンチマークに影響する。 >>343 メモリの占有率を調べたいなら、そういうソフト入れてベンチマーク取ればわかる。 そして結果を発表すると皆から感謝される。 むしろ、その式は人間が見やすいかどうかを考慮した方がいいと思う。 下記の中で最も負荷が少ないのはどれでしょうか? 1.printを使い一行ずつ出力 2.ヒアドキュメントで出力 3.別ファイルを作り読み取らせて出力 3は後々便利そうだけど、負荷が気になる…。 >>346 負荷が少ないって、どっちの? 「省メモリ」? それとも「CPU占有の少なさ」? >>346 >3.別ファイルを作り読み取らせて出力 >3は後々便利そうだけど、負荷が気になる…。 じゃあ外部ライブラリとかあまり使わない方がいいよ。CPANもね。 >>346 1.出力処理が遅い。 2.出力処理は早い。 3.良識ある人間のやること。 一般に、メモリ占有量の低いものの方がウェブには向いているよ。 >>350 そうか?次々とくる要求に迅速に対応するために処理速度を優先しない? webプログラムは、サーバへの負荷も気をつけないといけないと思うけど、 それよりも、トラフィックを一番に考えてる俺は間違ってますか? そんな細かい事ぐらいでサーバーから言われる事はまず無いので 私も処理速度を優先させるべきだと思うねぇ。 というか、気にするほど大して変わらない。 基地外なほど膨大なデータを扱うならまだしも。 想定同時アクセス1000くらいの小さな案件で、 鯖を用意してやるなら、保守性を一番においても問題ないと思う。 >>355 >想定同時アクセス1000 これって小さいの? 秒間同時アクセス数1000ってことだよね? 共有メモリを活用する、繰り返し使用する正規表現はlexで、 大きなプロセスは常駐させてローカルソケットでCGIと通信してCGIは小さく作る、 データベースは下手に使わない、巧く使える場合にだけ使用する。 >>354 サーバーがつんでるメモリーの量によってどっち優先かは変わると思われ。 メモリー使い切ったらswapのオーバーヘッドがかかってかえって遅くなるし。 まあ、最近のサーバーはメモリーを湯水のように持っているからそんなこと考える必要ないのかな? Perl5からPerlでもコンパイルした状態で設置できるようになったと読んだんですがどうすればできますか? >>359 perlccを使う。 使ってどの程度早くなるかは知らんけれどね。 >>358 共有鯖ならいくらメモリ積んでいようと割り当てられるのは 微々たるもの >>360 散々言われてていることだが、perlccではモジュールはろくすっぽ使えないので注意。 >>360 早速やってみたところかなり速くなりました。 でもサイズが2kちょいから800kほどに... >>363 perlcc使ったことあるけど、2kじゃなくて2MBになったよ mod_perlだと数倍早くなるのに perlcc だと1割くらいじゃない? ダブルクオートを極力使わないだけで結構速くなるらしい。 理由は説明しなくてもわかるよね? >>368 '"'でくくると中に'$'が入っているかを検査してるから? >>371 Yes she does! PHP のメーリングリストなんかでも、 速度を少しでも稼ぎたいときの小技として紹介されることがあるね。 すべてのルーチンを一つのファイルにまとめてしまうのより、 ひとつひとつルーチン毎にファイルを分けて、 一度に呼び出す方が負荷が大きいですか? >373 漏れもそれ思うんだが、ファイルをまとめようが分割しようが、 結局たいした大きさじゃないので、どっちもオンメモリってことない? 使わないコードを解釈させない為に分割するんであって、 分割しても常に全部使うのなら、まとめた方がシステムコールが 減っていいと思う。 Perl だったら CGI.pm でやってる遅延読込が参考になるかと。 あれはあれでメモリ食いそうだけど。 >>375 それじゃ、useでモジュール呼び出すより、 requireで、必要な所で呼び出す方が良いって事ですね。 >>376 別に必要になったところでuseすればいいんでないかい? そうそう、SelfLoaderかまして起動時には一部しか読み込まれないように工夫しないといかんね。 requireはそこに来た時点で読み込まれる。 function hoge() { require('hoge.php'); } hoge(); らなければ読まない。 Perlも同じく。 コメントを山ほど書いたら負荷になります? スクリプト自体軽くした方がいいんでしょうか。 >>382 富士山ほどのコメントを書いたら負荷になります。 >>382 わかるほどの差は出ないからちゃんと書いといたほうがいいよ >>386 体感できるほどの差ではない、つまり実質0 read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる