やっぱりawkは遅い
外部コマンドは遅い。できるだけbuilt-inコマンドを使おうって話。
シェルでよくあるんだけど、ある区切りの○番目を取ってきたい、っていう場面で
foo="aaaa,bbbb,cccc" bar=`echo $foo | awk -F, '{print $2}'`
ってやる時がある。
けど、これ、むちゃくちゃ無駄。一回しか実行されないなら大したボトルネックにはならないが、ループの中で使うと酷い事になりがち。
awkの場合
#!/bin/sh typeset -i i=0 while (( i < 10 )) do echo "aaaa,bbbb,cccc" | awk -F, '{print $2}' >/dev/null i=$(( i + 1 )) done
$ time ./awkTest.sh real 0m0.129s user 0m0.031s sys 0m0.098s
readの場合
カンマ区切りをどうやって? っていうとIFS
変数とread
コマンドを使う。
#!/bin/sh typeset -i i=0 while (( i < 10 )) do IFS=, read a b c <<EOF aaaa,bbbb,cccc EOF echo $b >/dev/null i=$(( i + 1 )) done
$ time ./readTest.sh real 0m0.024s user 0m0.012s sys 0m0.012s
たった10回のループでこれだけの差が出る。
ログファイルなど行数の多いファイルを読み込んだりして解析するようなものの場合、外部コマンドがボトルネックになりがちなので気をつけよう。
追記
コメント、トラックバックを受けるとGmailへ通知。さらにGmailからケータイへ転送されるようにしていたら、朝の4時半ごろにツッコミを受けてしまった。ツッコミを受けそうなタイトルだなと思っていながら変更しなかったオイラが悪いが...。しかも相手は弾子飼氏だよ。
オイラは保守・運用の人で開発の人じゃないからプログラマの世界は詳しくないけど、ちょっとしたスクリプトではPerl,Rubyが多いのかな。お勤め2〜3年くらいしかない経験上で話すけど、Perlは保守・運用の世界では嫌われる。何故ならお客さんもいっしょに関わってくる関係で(お客さんが)知らない言語で書いちゃダメなんだそうだ。
因みに、Perlスクリプトは数回見た事があるが、use
を使ったものを見た事が無い。困ったものだ。orzSstrict
そんなこんなでシェルばかり使っていたら数十行書くのにPerlを書くのが億劫になってしまった。というか大分忘れている。リファレンス無しでは書けそうに無い。
プログラマには想像できないかもしれないが、Cygwin VIMでコード色分けして書いている*1と、『なんでそんなカラフルなの...』と嫌な顔をされるくらいだ。CVS等のバージョン管理システムも無い。変更管理をエクセル表でやるくらいならCVS導入しろと思うのだが...。
「理解しやすい」は多分に主観的ではあるが、少なくとも
404 Blog Not Found:sh, awk, perl & ruby - やっぱりforkは遅いi=$)((i + 1 ))(
のようなギミックは不要だ。
痛いところを突かれてしまった。単純な計算にこんな事をしなければならないシェルは美しく無いのは承知している。それともwhile )(( i < 10 ))( && )(( i = i + 1 ))(
とでも書けば良かったかな...。