数を表す正規表現
まず数を正規表現だけで全て記載できるかということですが、この「経典」こと「プログラミング言語 AWK」の中でそこまで要求しているとは思えません。ここで書かれている例の正規表現で記述できていないものに何があって、それはどうやって表現できるかな? という程度のものと考えるのが適切だと思います。
ですから、id:lurdan さんの書かれている追記のようなもので全然問題ないと思います。
次に正規表現が複雑になることによる計算コストの増加ですが、以下のようにして調べてみました。test.dat は 20 万行の数 (整数 10 万、小数点付き 10 万) のファイルです。
簡単な正規表現の場合
$ cat isnum.awk #! /sur/bin/gawk -f # isnum.awk - return num if it is number { print isnum($0); } function isnum(n) { return n ~ /^[+-]?[0-9]+$/; } $ time original-awk -f isnum.awk test.dat > /dev/null original-awk -f isnum.awk test.dat > /dev/null 19.29s user 4.46s system 99% cpu 23.767 total $ time mawk -f isnum.awk test.dat > /dev/null mawk -f isnum.awk test.dat > /dev/null 3.31s user 0.90s system 99% cpu 4.216 total $ time gawk -f isnum.awk test.dat > /dev/null gawk -f isnum.awk test.dat > /dev/null 43.95s user 6.39s system 99% cpu 50.409 total $ time LC_ALL=C gawk -f isnum.awk test.dat > /dev/null LC_ALL=C gawk -f isnum.awk test.dat > /dev/null 19.73s user 4.77s system 98% cpu 24.888 total
複雑な正規表現の場合
$ cat isnum.awk #! /sur/bin/gawk -f # isnum.awk - return num if it is number { print isnum($0); } function isnum(n) { return n ~ /^[+-]?([0-9]+[.]?[0-9]*|[.][0-9]+)[eE]?[+-]?([0-9]+[.]?[0-9]*|[.][0-9]+)?$/; } $ time original-awk -f isnum.awk test.dat > /dev/null original-awk -f isnum.awk test.dat > /dev/null 18.97s user 4.34s system 99% cpu 23.398 total $ time mawk -f isnum.awk test.dat > /dev/null mawk -f isnum.awk test.dat > /dev/null 3.65s user 0.72s system 95% cpu 4.555 total $ time gawk -f isnum.awk test.dat > /dev/null gawk -f isnum.awk test.dat > /dev/null 55.32s user 6.15s system 99% cpu 1:01.55 total $ time LC_ALL=C gawk -f isnum.awk test.dat > /dev/null LC_ALL=C gawk -f isnum.awk test.dat > /dev/null 20.38s user 5.61s system 99% cpu 26.054 total
私の手元にある original-awk (いわゆる 'one true awk' で 「プログラミング言語 AWK」のサンプルを動作させるために作られたような awk です) と mawk と gawk です。
速度順に言えば、mawk < original-awk < gawk です。これは mawk がバイトコンパイルを行うため (今もやっているんでしたっけ?) 圧倒的に高速に処理し、gawk は glibc などの共通ライブラリの肥大化に伴い遅くなっているものと思われます。特に言語毎に正規表現が複雑になるため、環境変数 LC_ALL を C にしてやることで一気に高速化します。(それでも遅いですが・・・)
さて、本題の正規表現の複雑さによる速度の低下ですが、awk のバリアントによる差はありますが、私の環境で試す限り正規表現による差はほとんどありませんでした。特に 'one true awk' で差異がないことから、本設問の解答は「ほとんど変わらない」または「変わらない」で良いと思います。
- 作者: Alfred V.Aho,Brian W.Kernighan,Peter J.Weinberger
- 出版社/メーカー: シイエム・シイ
- 発売日: 2001/03/01
- メディア: ?
- 購入: 1人 クリック: 22回
- この商品を含むブログ (10件) を見る