How often does the state of the machine change? If it remains constant for some time, then I translate it into a hard-coded procedure in any language that I prefer.
Where does the transition diagram of a finite state machine come from? Does this come from regex? You know that you can translate this directly into structured code without first creating an arc set. In fact, the easiest way to write this code is to get started.
Then I either just make this part of the application, or I dynamically compile and link it to the dll and load dynamically. The latter takes only a couple of seconds.
The final destination machines are so simple that they generally need to be run for a small fraction of the time required to load the I / O buffer. They should not do unnecessary memory allocation, building a data structure, any of these OO hoo-haw.
Remember that the final state machine, represented as a set of states and arc tuples, is a theoretical model. It exists, like Turing machines, to prove theorems about this. Like a Turing machine, this is not necessarily a good technique for implementing code.
Just to show you what I mean, consider a regular expression for decimal integers:
dd*
where 'd' means a number. As the final machine (tuples), this will be:
A d -> B B d -> B
as a code it will be:
char c = getc(); if (DIGIT(c)){ c = getc(); while(DIGIT(c)){ c = getc(); } }
See the similarity of this code to regex? Do not think c = getc() as "get the next character c". Think of it as "accept the current character c." Hopefully you will see that the code cannot be much faster than this.
If you really start with an arc set, you can generate this:
c = getc(); A: if (DIGIT(c)){c = getc(); goto B;} goto END; B: if (DIGIT(c)){c = getc(); goto B;} goto END; END:
which is spaghetti code, but no more than an arc set, and it will be as fast as structured code. (Actually, this is more or less what the compiler converts your structured code into.)