理系学生日記

おまえはいつまで学生気分なのか

忍者TOOLS

シェルスクリプトのバッドパターン

シェルスクリプトでバッチ組んだけど性能が出ません、止まってるように見えます、みたいな相談を受けた。
大量のデータを扱うバッチだったので DB 処理待ちになっているもんだと思っていたのだけれど、状況を調べてみると DB サーバ側の負荷はまったくなく、むしろバッチを動かしているサーバの CPU が 100 % に張り付いている。
ソース読ませてもらったら、以下のようなコードがあった。hogefile が数十万行のそれなりに大きなテキストファイルだったので、まぁこのコードが原因でしょうね。

while read line 
do
    var1 = echo $line | awk .....
    var2 = echo $line | hogehoge | fugafuga
done < hogefile

CPU が 100% に張り付いたのは、hogefile 1 行 1 行の処理でプロセスが生まれては消えるを繰り返すことが原因だろう。いったい何回 fork させるの、どれだけのプロセスを生んで殺すの…という話。実際に 1 秒に何行処理できているのかを計測したところ、秒間で 10 行以下しか処理できていなかった。そりゃ止まったように見えるわ、みたいなかんじ。

while 文の中の処理はわりあい単純だったので、行毎に while 文を回すのではなく、ファイルをパイプで処理するようにしてくださいみたいなアドバイスをした。生成されるプロセス数が激減し、fork による負荷も同様に激減する。
とりあえず 数百倍は速くなったっぽい。