Il caso dopo caso è efficiente?

5

Solo una domanda a caso sull'efficienza dei casi di interruttori caso per caso; è il seguente codice (presuppone lo pseudo codice):

function bool isValid(String myString){
   switch(myString){
   case "stringA":
   case "stringB":
   case "stringC":
      return true;
   default:
      return false;
}

più efficiente di questo:

function bool isValid(String myString){
   switch(myString){
   case "stringA":
      return true;
   case "stringB":
      return true;
   case "stringC":
      return true;
   default:
      return false;
}

O le prestazioni sono uguali? Non sto pensando in un linguaggio specifico, ma se necessario supponiamo che sia Java o C (per questo caso sarebbe necessario utilizzare i caratteri anziché le stringhe).

    
posta RandomGuy 23.06.2012 - 20:53
fonte

3 risposte

5

Dipende molto dal compilatore. Tuttavia, come regola semplice, switch utilizza l'istruzione JUMP (equivalente all'istruzione GO TO) per iniziare dal punto desiderato sulla condizione di corrispondenza. Quindi, in questo caso, se più condizioni salta allo stesso segmento o codice o diverso, non aggiunge ulteriore controllo condizionale.

Un altro confronto:

il codice if(arg == CASE_1 || arg == CASE_2 || arg == CASE_3) aggiungerà effettivamente il controllo condizionale con arg == CASE_1 così come arg == CASE_2 anche se arg è in realtà CASE_3. D'altra parte, il passaggio comporterà solo 1 operazione di confronto in entrambi i modi.

In entrambi i casi precedenti, penso che il numero di cicli della CPU sarà identico, perché ammonteranno a 1 controllo di condizione e ad una istruzione pop. Tuttavia, la versione successiva richiederà altre 2 istruzioni ridondanti in memoria. Quindi è leggermente inefficiente dal punto di vista della dimensione del codice.

    
risposta data 23.06.2012 - 21:01
fonte
4

L'efficienza non dovrebbe essere la tua preoccupazione qui.

La complessità e la manutenibilità del codice dovrebbero essere le tue preoccupazioni principali qui.

Dovresti sapere se stai operando al livello appropriato di astrazione qui.

Enfasi: perché senti la necessità di raggiungere questo martello (cioè molte dichiarazioni case in un blocco switch )?

Raccomandazione: dai un'occhiata a questa domanda su SO .

    
risposta data 23.06.2012 - 21:17
fonte
3

Il layout delle etichette delle maiuscole non è il collo di bottiglia di questo codice: il confronto tra stringhe è.

Tipicamente per le etichette dei casi il compilatore sta per generare una semplice tabella di salto e passare alla riga di codice appropriata in base al valore da testare. Questa è una conoscenza importante: il codice che scrivi in un linguaggio di alto livello spesso ha ben poca somiglianza con la rappresentazione di basso livello che il compilatore genera. Quindi non puoi fare un'osservazione diretta sulle prestazioni potenziali semplicemente osservando il codice di alto livello.

Nel caso di C # / Java / qualunque, le lingue che consentono alle stringhe di apparire come voci dell'etichetta del caso, le regole cambiano. Ora il compilatore non può più generare una tabella di salto, deve fare un sacco di confronti tra stringhe per determinare il ramo appropriato da seguire. E le stringhe sono lente.

Se sei preoccupato dell'efficienza di questo codice, allora considera di usare un enum. Se non puoi (o non lo farai), puoi ottenere prestazioni extra ricavandone le condizioni di maggior successo nella parte superiore. Se questa non è una parte critica dal punto di vista delle prestazioni del tuo programma, allora non fare nulla: è già abbastanza buono.

    
risposta data 23.06.2012 - 23:37
fonte

Leggi altre domande sui tag