以前幕張で鬱プロジェクトやってたという話は書きましたが。
今メインでやってるプロジェクトが暇なのを見抜かれて、ここ一週間ほどヘルプに行ってました。
ということでまとめ。長いので注意。
■目的とか
なんか遅いバッチ処理があるから、それを速くしてくれ、とのこと。
ざっくり聞いた話だと、無駄に DB にアクセスしまくってるんだそうな。
ロジックいじればかなり速くなるんではなかろうか。
アルゴリズムとかそのへんは(周りに比べると)得意分野なので、実は腕の見せ所だったり?
とちょっぴり期待。
■ドキュメント
ということで、ドキュメント読んでロジック理解しようとしたんですが…なんだこれ。
別ドキュメント参照したと思ったら、またそこから元のドキュメント参照してたりして。
ドキュメント読むのにわざわざフロー記述したのは初めてですよ。

(こんなの。Excel で作成)
■プロファイリング
で、結局よくわからないので、普通に時間計測してボトルネックを調べることに。
prof とか gprof が入ってない(入れたりもできない)ので、とりあえず tprof とやらを使ってみる。
su
tprof -v -s -p ./hoge -x ./hoge
とかなんとか実行してみたらなんか大量にエラー吐いた。これもダメっぽい。
仕方ないので、C のソースに時間計測の処理を埋め込むことに。
Perl で
・関数の一覧を抽出
・関数名を元にグローバル変数の宣言
・関数の冒頭(宣言部の直後)に時間測定処理挿入
・関数の終了部(return 直前)に時間測定処理挿入
・main の終了部で計測結果出力
みたいな変換をするスクリプト書いた。
2〜3 時間で書けたので、まぁ上出来。
■静的 SQL 化
で、計測してみると明らかにボトルネックになってる部分があった。
SQL を文字列で組み立てて、動的 SQL で UPDATE している部分。
静的 SQL に書き換えれば速くなるんだろうけど・・・これがめずらしく必要に迫られて動的 SQL を使ってる部分だったり。
・HOGE 列の更新仕様
intFlag == 1 であれば FUGA 列の値で更新、それ以外の場合更新なし
みたいな感じで、条件によって UPDATE する列の数まで変わってくるから、教科書的には「動的 SQL を使いましょう」っていう部分。
でもここで小細工実行。
UPDATE 〜
SET HOGE = CASE :intFlag WHEN 1 THEN FUGA ELSE HOGE END
こんな感じで更新条件もホスト変数にしてやって、SQL の中で条件判断することで、静的 SQL 化が可能だったり。
条件に合致しない場合は元の列の値で UPDATE するところがポイント。
# :intFlag は DB2 の組み込み SQL っぽい表現なので、わからなかったら無視してください
で、静的 SQL にすると、その関数のパフォーマンスが 30 倍とかに向上。
動的 SQL ってそんな重かったのか・・・
キャッシュが使われればそんな大げさにパフォーマンス変わらないと思ってたんだけど。
その他でも動的 SQL がいくつかあったので、それらも同様の修正。
データ量が少ない状態でテストしても、バッチ処理全体で 5 倍程度の速度が出てたり。
データが多い状態だったら 10 倍くらいは行きそう?
これだけ速くなるとなかなか気分がいいなー。
■テスト
で、以前のテストデータがあったので、それを使って回帰テストやって終了・・・のはずだったんですが。
ここで難航。
・テストデータが使えない
(テーブルのレイアウトが変更になってるのに、それに対応してなかったり)
・テスト結果が食い違ってる
(仕様変更が入ったのに、テストデータが更新されてない)
・仕様変更の際に、ソースだけ修正されててドキュメントが更新されていない
(テスト結果が食い違う原因がわからない)
みたいな感じで・・・。
仕方ないので、ソースコードをちまちま追ったりデバッグコードを入れたりしてテストデータの修正とか。
どうやらテスト結果が一致しない原因は、仕様変更だけじゃなくてデグレードもあるっぽい。
とりあえず関数修正したら単体テスト&回帰テストはやってください・・・お願いですから。
■鬱
ということで、
なんか嫌気が差してくる
↓
さっさとこんな作業終わらせよう、と残業
↓
結局終わらなくて翌日に持ち越し
↓
睡眠時間削られる
という嫌な感じのサイクルに突入。
結構鬱っぽくなってました。
でもまぁ、このバッチ処理が軽くなれば運用担当者の負担が減るわけで。
よく考えたら、自分が作ったプログラムで目の前の人を喜ばすことができる数少ない機会では?
と、前向きに考え直しまして。
あっさり鬱から回復。
■結果とか感想とか
ドキュメントの更新がなくて仕様不明になってる部分以外はなおしました。
コメントの修正もやっときました。
まぁ、それなりにいい経験でしたけど、やっぱ幕張は遠いです。
あと、客先(スーツ着用)なので 2 割増くらいで疲労が溜まります。
ひさびさに見た顔とかもあって良かったところもあるんだけど、やっぱりもう行きたくないな。