ステートマシンはどのくらいの頻度で変更されますか? しばらく変わらない場合は、好きな言語でハードコードされたルーチンに変換します。
ステートマシンの遷移図はどこから来たのですか? それは正規表現から来ていますか?最初にアークセットを構築しなくても、それを構造化コードに直接変換できることはご存知でしょう。実際、最初からそのコードを書く方が簡単かもしれません。
次に、アプリのその部分を作成するか、動的にコンパイルして dll にリンクし、動的にロードします。後者はほんの数秒かかります。
有限ステート マシンは非常に単純であるため、基本的には、I/O バッファーの読み込みにかかる時間のごく一部で実行する必要があります。不必要なメモリ割り当て、データ構造の構築、その OO ホーホーのいずれかを行うべきではありません。
ステートとアーク タプルのセットとして表される有限ステート マシンは理論モデルであることを思い出してください。チューリングマシンのように、それに関する定理を証明するために存在します。チューリング マシンと同様に、コードでの実装手法として必ずしも優れているとは限りません。
私が言いたいことを示すために、10 進整数の正規表現を考えてみましょう。
dd*
ここで、「d」は数字を意味します。有限状態マシン (タプル) としては、次のようになります。
A d -> B
B d -> B
コードとしては次のようになります。
char c = getc();
if (DIGIT(c)){
c = getc();
while(DIGIT(c)){
c = getc();
}
}
このコードが正規表現と似ていることがわかりますか? c = getc()
「次の文字 c を取得する」と考えないでください。「現在の文字 c を受け入れる」と考えてください。コードがこれよりはるかに高速になることはないことがお分かりいただけると思います。
実際にアークセットから開始する場合は、次のように生成できます。
c = getc();
A:
if (DIGIT(c)){c = getc(); goto B;}
goto END;
B:
if (DIGIT(c)){c = getc(); goto B;}
goto END;
END:
これはスパゲッティ コードですが、アーク セット以上のものではなく、構造化コードと同じくらい高速です。(実際、これは多かれ少なかれコンパイラが構造化コードを変換するものです。)