y-matsui::weblog

電子楽器、音楽、コンピュータ、プログラミング、雑感。面倒くさいオヤジの独り言

パフォーマンス改善

次々と機能を追加してきたせいで、動作はするものの、醜悪なパフォーマンスになってきた。(汗)
ここはひとつひとつ解きほぐしていくしかない・・・ということで、今回とりあえず思いついた4点ほど改善を行った。
1:HTMLとASPの切り替え回数を少なくする
2:引数の見直し
3:DBアクセスのオーバヘッド
4:レスポンスバッファーの制御
上記4点で、体感できるほどの効果が出た。(特にDBアクセス部分の見直しは効果絶大)

1はASPPHPなどHTMLと混在するWebスクリプトでは避けがたい部分。HTMLソース内に変数を使えるものだから、ぽんぽんとプログラムを埋め込んでしまう。Webサーバは1セッションのレスポンスのために、アプリとHTTPサービスの切り替えを頻繁に行うのであるから、できるだけ切り替えの回数を少なくした方が良い=処理をできるだけ大きなブロック単位にする(・・と良いらしい)。塵も積もれば・・・という感じか。

2:は関数により様々だと思われるが、参照渡しと値渡しの問題。
一般には参照渡しの方が高速、独立性を高めるなら値渡しなどと言われている。元の変数に加工した結果を戻すのか(参照渡し)、戻さないのか(値渡し)という使い分けが頭にあるが、結構難しい問題だと思う。妙な副作用を抱え込みたくないし、かといってメモリをバカ食いしたり、結果に不整合が出てきたりしたら大変だ。
とりあえず、元に値を返さないと分かっている関数で参照渡しを徹底するか・・。と

3:DBアクセスのオーバーヘッド
特に今回効いたのは、DBアクセスのオーバーヘッド。
DB接続の待ち時間が非常に大きいことは分かっていたが、本体プログラムからやたらとコールされる関数の引数にDBConn(DB接続の参照)を渡していた。引数としてレコードセットを渡すようにし、DBコネクションを流用するようにしたらかなり高速化された。
「高速化された」と喜ぶ前に、同じレコードを参照するのにわざわざ別コネクションからIdxを指定してレコードにアクセスする関数の作り方がタコなのである。(汗)
こういう無駄なリソース食いを他にもやっていないかどうかをすべて見直す必要がありそう。

4:レスポンスバッファーの制御
出力を一括でクライアントに返すのが速いのか、チマチマとその都度返してやった方が速いのか。
CSV書き出しなどのストリームの場合は、バッファに溜め込んで一気に出力!とやっているが、検索結果一覧表示はどうなんだろう?ブラウザによっても表組みの描画方法が違うと聞いたことがある。IEではどうやら逐次描画しているようだが、FireFoxなどは最後のタグまできちんと確認してから書き出すため、バッファリングしたのと同じような感じ。IEにターゲットを絞るのであれば、検索結果一覧も1行づつ返した方が速いかもしれない。(でもこれ、ネットワーク環境がインターネットなのかLANなのかでも違うんだろうなぁ)
とりあえず、Response.Buffer=Trueを打ち込んでおいて、処理の一塊でResponse.Flushで吐き出すように変更。

その他:
プログラムの書き方や共通関数モジュールの細分化を見直すのもパフォーマンスに影響しそう。
以前、内部修正(処理内容を変えずにコードをスリム化すること)をしたら、総コード量で1割、単体では6割も削減できた例がある。ASPのようにコンパイルしないプログラム(スクリプト)では特に、ソースをできるだけスリムにするのが第一ですな。(滝汗)