Gawk (GNU awk) のパフォーマンス

以前にGNU grepのパフォーマンス向上についてお話しましたが、実はGawkのマッチング部分にはGNU grepと同じコードが使われています。ということは、Gawkのパフォーマンスも向上しているのでしょうか?

Gawk 3.1.7

まずは、Red Hat Enterprise Linux 6にバンドルされているGawk 3.1.7でテストしてみました。

$ yes jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj | head -10000000 >../k

$ time -p env LC_ALL=C gawk '/a|b/ { print }' ../k
real 2.65
user 2.58
sys 0.07

$ time -p env LC_ALL=ja_JP.eucJP gawk '/a|b/ { print }' ../k
real 13.96
user 13.86
sys 0.09

Gawk 4.1.1

執筆時点の最新版Gawk 4.1.1 (2014-04-08リリース)でテストしてみました。

$ time -p env LC_ALL=C ./gawk '/a|b/ { print }' ../k
real 2.29
user 2.22
sys 0.07

$ time -p env LC_ALL=ja_JP.eucJP ./gawk '/a|b/ { print }' ../k
real 5.37
user 5.28
sys 0.08

Gawk開発中版 (Git)

執筆時点で最新のスナップショットを取得してテストしてみました。

$ time -p env LC_ALL=C ./gawk '/a|b/ { print }' ../k
real 1.63
user 1.57
sys 0.05

$ time -p env LC_ALL=ja_JP.eucJP ./gawk '/a|b/ { print }' ../k
real 1.63
user 1.56
sys 0.07

まとめと解説

Cロケールで1.6倍、非UTF-8マルチバイト・ロケール(EUC-JP)では8.5倍もパフォーマンス向上していました。

ところで、パフォーマンス向上したといっても、この数値はGNU grepよりも4倍くらい遅いです。awkでは変数RSに値を設定することで行区切りを変更することができ*1、このハンドリングのために遅くなっています。

*1:Gawkでは正規表現を使用することも可能です。