What is the best (when performance matters) way to implement a state machine in C #?

The following options have appeared:

Using the goto statement:

Start:
    goto Data
Data:
    goto Finish
Finish:
    ;

using the switch statement:

switch(m_state) {
    case State.Start:
        m_state = State.Data;
        break;
    case State.Data:            
        m_state = State.Finish;
        break;
    case State.Finish:
        break;
}

using goto and switching between each other:

switch(m_state) {
    case State.Start:
        goto case State.Data2;
    case State.Data1:
        goto case State.Finish;
    case State.Data2:
        m_state = State.Data1;
        //call to a function outside the state machine
        //that could possibly change the state
        break;
    case State.Finish:
        break;
}

I prefer the first option using the goto statement because it is faster and less verbose. But I'm not sure if this is the best option. Performance may be reasonable, but when it comes to readability, I don't know. That is why I am asking this question. Which option do you prefer and why?

+3
source share
5 answers

goto , , .

goto , , , .

, , . , , yuu . , , goto.

, , , .

+2

/ . :

returnvalue Start() {
    return Data();
}

returnvalue Data() {
    return Finish();
}

returnvalue Finish() {
}

, goto (, ). , #/JITter, , . (, IMHO), goto , , ( , ).

goto case. ? goto ( switch), , .

: , . goto . goto case , . ( - ), goto case.

+3

- , switch.

switch(m_state) {
        case State.Start:
                m_state = State.Data;
                break;
        case State.Data:                        
                m_state = ComputeNextState();
                break;
        case State.Finish:
                break;
} 

, switch ( Goto) .

EDIT:

"goto case" :

switch(m_state) {
        case State.Start:
                m_state = State.Data; // Don't forget this line!
                goto case State.Data;
        case State.Data:                        
                m_state = ComputeNextState();
                break;
        case State.Finish:
                break;
} 

. ( , "m_state" ), .

+2

4- .

statemachine. , ,

He has some flaws. Manipulating the state from the outside of the iterator is impossible.

I'm also not sure if this is very fast. But you can always do the test.

+2
source

Personally, I prefer the second with goto, since the first requires an unnecessary loop step (for example) in order to transition to a new state

0
source

Source: https://habr.com/ru/post/1720965/


All Articles