« oregexp動かない・・・ | Main | ErlangとPerlの速度比較 その2 »

Saturday, April 21, 2007

regexpの代わりにparser

Erlangで正規表現がイマイチ使えないので,パーサを書く方法を試してみた.
HaskellのParsecのようなライブラリ parser.erl を使ってみた.

実行回数を1桁増やして,0xffff回実行にして,再度PerlとErlangで比較.

方法言語時間(sec)
parserErlang (beam)2.843180
Erlang (native)1.079725
Erlang (beam+smp)3.035176
Erlang (native+smp)0.776946
正規表現Perl0.197326


Perlの正規表現最強.
まぁ,言語自体にCで最適化されているエンジンが搭載されているのと比較するのがアレなのかもしれないけど. それにしても,もう少し速い方法があるといいんだけども...
nativeコンパイルでだいぶ速くなるのが救いかな?
oregexpを使うとかPCREを外部で呼び出すとかしても,ドライバのオーバーヘッドが大きそうだから,iconvで同一回数回したときの0.6秒よりは小さくならなさそうだし,互角なレベルに持って行くのは厳しそう.
言語レベルで内部構造べったりな感じで拡張する方法があれば良いけど,マニュアルを見る限りはなさそうだし.(互換性のためにあえてそういう仕様にしているぽい感じ)
とりあえず,正規表現を使うのに比べて10倍以上は速くなっているから,こんなもんかなぁ.

ソースコードは以下の通り.(適当なところで改行いれてあります)
-module(strparser).
-export([bench/0, bench/1]).

bench() ->
    Time = timer:tc(strparser, bench, [16#ffff]),
    io:format("~w~n", [Time]).

bench(0) ->
    0;
bench(N) ->
    String = "12.34.123.12 - - [17/Apr/2007:23:53:13 +0900] \"
    GET /html/1234.html HTTP/1.1\" 200 6980 \"http://www.
    mikage.to/html/1234.html\" \"Mozilla/4.0 (compatible; MS
    IE 6.0; Windows NT 5.1; SV1)\"\n",
    {Str1, Str2} = parser:parse(parser:pAnd([
        parser:pMany1(parser:pSat(fun (C1) ->
            not lists:member(C1, " ") end)),
        fun parser:pSpace/1,
        parser:pMany1(parser:pSat(fun (C1) ->
            not lists:member(C1, " ") end)),
        fun parser:pSpace/1,
        parser:pMany1(parser:pSat(fun (C1) ->
            not lists:member(C1, " ") end)),
        fun parser:pSpace/1,
        parser:pChar($[),
        parser:pMany1(parser:pSat(fun (C1) ->
            not lists:member(C1, "]") end)),
        parser:pChar($]),
        fun parser:pSpace/1,
        parser:pChar($")
    ]), String),
    {Str3, Str4} = parser:parse(parser:pAnd([
        parser:pMany1(parser:pSat(fun (C1) ->
            not lists:member(C1, "\"") end))
    ]), Str2),
%   io:format("~s~n", [Str3]),
    bench(N - 1).

|

« oregexp動かない・・・ | Main | ErlangとPerlの速度比較 その2 »

Comments

The comments to this entry are closed.

TrackBack


Listed below are links to weblogs that reference regexpの代わりにparser:

« oregexp動かない・・・ | Main | ErlangとPerlの速度比較 その2 »