2012-12-12 7 views
7

Durante la mia intervista, mi è stato chiesto di realizzare una macchina a stati per un sistema con 100 membri in cui ogni stato a sua volta dispone di 100 eventi, risposi 3 seguenti approcci:Intervista: puntatori a funzione vs caso interruttore

  • se -else
  • switch-case
  • puntatori a funzione

Se-else ovviamente non è adatto per una tale macchina a stati, quindi comparatore principale era tra switch-case vs puntatori a funzione, ecco t il confronto secondo la mia comprensione:

  • Velocità entrambe sono quasi le stesse.
  • Switch-case è meno modulare dei puntatori di funzioni
  • I puntatori di funzione hanno più memoria in testa.

Qualcuno potrebbe confermare se la comprensione precedente è corretta?

+4

I puntatori di funzione sembrano l'unico approccio valido in questo caso. Sì, è sovraccarico nella velocità di accesso, ma è una soluzione modulare e flessibile. –

+2

Non riesco a immaginare un hard coding di 100 stati, vorrei piuttosto aggiungerli all'inizializzazione su una macchina a stati. Questo evita la scaletta di if-else/switch-case di 10 schermate e rende * molto * più facile il test e la modifica –

+1

Non sono sicuro se questo soddisferà l'intervistatore, ma sul lavoro vorrei semplicemente usare [Ragel] (http: //www.complang.org/ragel/). Hai una velocità incredibile (per esempio 'goto' based) * e * più facile debugging (Ragel può scaricare il grafico di transizione di stato in formato punto per consumare Graphviz). – unthought

risposta

1

Potrebbe esserci una variante dell'approccio del puntatore a funzione: una struttura che include un puntatore di funzione e altre informazioni. Quindi potresti lasciare che una funzione gestisca diversi casi.

Oltre a questo, penso che tu abbia ragione. Inoltre, considererei il sovraccarico relativo alla memoria e alla velocità che vale la pena prendere in considerazione, ma si spera abbastanza piccolo da essere ignorato alla fine.

+0

Non è stato possibile ottenere esattamente ciò che intendevi per struct con l'approccio del puntatore a funzione, se tutte le funzioni eseguono funzionalità indipendenti, in che modo potresti avere una funzione per servire più casi? – user1897724

+0

@ user1897724 Se due stati sono quasi gli stessi, ma differiscono in un aspetto, questo potrebbe valerne la pena. – glglgl

+0

@glglgl Conosci qualche buona lettura su questo particolare argomento? – Blackninja543

0

Non so cosa volessero ascoltare i vostri intervistatori e spero che questo non sia fuori tema ma se intervistassi qualcuno darei dei punti per conoscere i pro ei contro delle strutture esistenti prima di giustificare il lancio del proprio, specialmente a quella scala.

alternative C++ (se si possono usare, grazie alla glglgl per aver ricordato che ti sembra di voler C) sarebbe:

Boost.MSM anche se incredibilmente veloce è fuori questione in quella scala. I motivi sono i tempi di compilazione, mpl :: vector/list e perché si avrebbe un gigantesco file sorgente.

Boost.Statecharts può funzionare con 100 stati ma 100 eventi per stato ridurrebbe al massimo i limiti mpl :: vector/list. Personalmente se avessi 100 eventi in uno stato, proverei comunque a raggrupparli e ad usare reazioni personalizzate, ma ovviamente dipende dall'applicazione.

Non vedo alcuna ragione per cui la macchina a stati di Qt non scala in modo così grande (correggimi se ho torto) ma i suoi ordini di grandezza sono più lenti, quindi non lo uso mai.

L'unica buona C alternativa che conosco è:

QP che è disponibile in C e C++ e può scalare quella grande, ha una buona organizzazione ed è "più di uno stato-macchina" in cui il programma gestisce evento code, concorrenza e gestione della memoria ecc. Il rollover può produrre prestazioni migliori (in base alle tue capacità e al tempo impiegato) ma va notato che la gestione della memoria degli eventi probabilmente finirà per richiedere più ottimizzazione che l'implementazione della macchina statale è autonoma. QP fa questo per te e abbastanza bene.

+0

Boost è C++ e anche Qt, non è vero? – glglgl

+0

corretto, ho trascurato il tag C dell'OP, Qt è anche C++ quindi lascia solo QP (che è anche disponibile sia in C che in C++) – odinthenerd

0

È possibile specificare ulteriori dettagli sui propri stati ed eventi. Supponi che il tuo stato sia un numero intero continuo.Quindi è possibile

  1. Scrivere una tabella per contenere tutti gli stati e la funzione di gestore di stato su di esso. Quando si riceve un evento, fare riferimento a questa tabella e chiamare la corrispondente funzione del gestore.

  2. Per ogni stato, scrivere una tabella che contiene tutti gli eventi e la relativa funzione di gestore eventi. Cerca questa tabella durante l'elaborazione dell'evento sullo stato.

la complessità temporale di questi 2 tavolo guardando in alto è O (1), e lo spazio complessità è O (m * n)

Tuttavia, come si può avere FSM con 100 Stati e evento con 100 tipi? Ti suggerisco di semplificare la progettazione del tuo FSM e il numero 1 ~ 100 può essere il parametro di un particolare evento.