シェルスクリプティングでは様々なコマンドを組み合わせてスクリプトを書きますが、同じ結果を得るコマンドでも、コマンドの組み合わせによってその処理速度は大きく変わります。
例えばあるストリングを取り出すためのコマンドについて考えてみましょう。
grepに h(ファイル名なし)とo(該当箇所のみ抜粋)のオプションをつければ簡単にマッチするストリングを取り出すことができますが、実はこれはあまり速い方法ではありません。
それよりもsedを使う方が処理速度としては断然速いです。
では例として、xmlタグの中から一つの要素を取り出そうとします。
<example color=”red” size=”5″>テスト</example>
という一行があり、この中からredを取り出すなら。
grepを使用する場合は
grep -Eo ‘color=”[^”]+”‘ | sed ‘s/^color=”//’ | sed ‘s/”$//’
たとえばこんなコマンドでgrepの-oオプションで該当箇所だけを取りだしてからsedでいらない部分を除くと、redがアウトプットとして取り出せますが、このgrepが入ったパターンだと処理速度は遅くなります。
代わりにストリングを取り出すだけで、形の決まったxmlであれば
sed ‘s/^.*color=”//’ | sed ‘s/”.*$//’
これだけで済みます。インプットの形によっては正規表現が必要となり面倒ですしgrepより感覚的ではありませんが、grepでマッチを探すより、前後を全てsedで取り除いてしまう方が速いです。
例えばこのような感じで同じインプットから同じredを取り出すコマンドを上記のgrepバーションとsedバージョンを1000繰り返すスクリプトであれば、
#!/bin/bash input='<example color="red" size="5">test</example>' START=$(date +%s.%N) for i in {1..1000}; do output=$(echo $input | grep -Eo 'color="[^"]+"' | sed 's/^color="//' | sed 's/"$//') done echo $output END=$(date +%s.%N) DIFF=$(echo "$END - $START" | bc) echo $DIFF START=$(date +%s.%N) for i in {1..1000}; do output=$(echo $input | sed 's/^.*color="//' | sed 's/".*$//') done echo $output END=$(date +%s.%N) DIFF=$(echo "$END - $START" | bc) echo $DIFF
red
2.252697176
red
1.563371214
結果はsedのみの方が約1.5倍速くなります。
とにかくsedは処理が速いコマンドなので、シェルスクリプトの中ではsedでできるものはなるべくsedに置き換えることがパフォーマンス向上に役立ちます。