In che modo un dizionario è migliore di un grande interruttore, quando si mappano i dati all'azione? [duplicare]

1

Spesso vediamo cose del genere in codice:

void myFunction(string someValue) {
    if (someValue == "a") {
        // ...
    } else if (someValue == "b") {
       // ...
    } else if (someValue == "c") {
       // ...
    } else {
       // ...
    }
}

Questo è un esempio di base della mappatura dei dati alle azioni. Fare ciò usando una grande switch o una lunga serie di if else-if è considerata una cattiva pratica.

Un approccio comune consiste nell'usare un Dictionary (o HashMap , ecc.) come una sostituzione. Per esempio:.

Dictionary<string, Action> _actions = new Dictionary<string, Action>();

// .. fill in the dictionary somewhere

void myFunction(string someValue) {
    _actions[someValue]();
}

In qualche modo si sente come un approccio più elegante. Comunque non vedo come sia così.

Quando si mappano i dati alle azioni, in che modo un dizionario è migliore di un grande / crescente switch ?

    
posta Aviv Cohn 22.02.2015 - 00:37
fonte

2 risposte

3

Che cosa succede se hai centinaia di valori tra cui scegliere? Come sarebbe l'affermazione del tuo interruttore? Sarebbe mantenibile? Penso di no.

Ciò che si perde usando una mappa è un impatto minimo nelle prestazioni a causa di una maggiore deviazione della direzione: ciò che si ottiene è enorme, enorme aumento della manutenibilità.

Come accennato da greyfade nei commenti, puoi anche cambiare la mappa durante il runtime, non stai codificando i possibili valori dell'istruzione switch.

    
risposta data 22.02.2015 - 00:47
fonte
2

I termini di leggibilità e manutenibilità ti faranno meglio con un dizionario se ci sono qualcosa di più di cinque o sei azioni.

In termini di prestazioni (a seconda della lingua, della versione, dell'hardware ecc. ecc.) il compromesso è: -

Switch: un confronto per valore di test più un ramo per azione se si assume che i valori siano equamente distribuiti, quindi si media il 50% dei test su ogni passaggio attraverso lo switch. (Per i programmi C con valori interi piccoli (come un EVAL), questo sarà ottimizzato per una tabella di branche per passaggio).

Dizionario: calcola l'hash, la voce di ricerca, quindi il ramo.

Quindi dite le sue 20 istruzioni per calcolare un hash intero e un altro 10 per de-referenziare la vostra tabella di diramazione, quindi il dizionario inizia a sovraperformare l'interruttore codificato dopo soli 60 valori di test.

    
risposta data 22.02.2015 - 01:26
fonte

Leggi altre domande sui tag