2009-11-16 7 views
5

Domande correlate:Benefits of using short-circuit evaluation, Why would a language NOT use Short-circuit evaluation?, Can someone explain this line of code please? (Logic & Assignment operators)Perché utilizzare il codice di cortocircuito?

Ci sono domande circa i vantaggi di un linguaggio utilizzando il codice corto circuito, ma mi chiedo quali sono i vantaggi per un programmatore? È solo che può rendere il codice un po 'più conciso? O ci sono motivi di prestazioni?

Non sto chiedendo di situazioni in cui devono essere valutati in ogni caso due entità, per esempio:

if($user->auth() AND $model->valid()){ 
    $model->save(); 
} 

Per me il ragionamento non è chiaro - dal momento che entrambi hanno bisogno per essere vero, si può saltare più validazione del modello costoso se l'utente non può salvare i dati.

Questo ha anche un (a me) scopo evidente:

if(is_string($userid) AND strlen($userid) > 10){ 
    //do something 
}; 

Perché non sarebbe saggio per chiamare strlen() con un valore non stringa.

Quello che mi chiedo è l'uso del codice di cortocircuito quando non influisce su altre dichiarazioni. Ad esempio, dalla pagina di indice di default di Zend Application:

defined('APPLICATION_PATH') 
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application')); 

Questo avrebbe potuto essere:

if(!defined('APPLICATION_PATH')){ 
    define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application')); 
} 

o addirittura come una singola istruzione:

if(!defined('APPLICATION_PATH')) 
    define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application')); 

Allora perché usare il breve codice del circuito? Solo per il fattore 'coolness' di utilizzare gli operatori logici al posto delle strutture di controllo? Consolidare le istruzioni nidificate if? Perché è più veloce?

+0

Una nota sulla velocità: se si dispone di un compilatore a metà decente, verrà generato lo stesso codice macchina per istruzioni if ​​e cortocircuiti. Se non lo fai, sta producendo codice sufficientemente cattivo che alcuni dei cicli aggiuntivi da una microottimizzazione di livello sorgente andranno persi nel rumore. Molto semplicemente, non è importante. –

+0

@David Vale anche per i linguaggi di scripting? –

+0

@TimLytle nelle lingue interpretate è possibile avere comportamenti diversi a causa di diverse analisi e interpretazione da eseguire. I compilatori ne traggono vantaggio prima che il codice abbia un'opportunità di esecuzione. –

risposta

4

Per i programmatori, il beneficio di una sintassi meno prolissa rispetto ad un altro sintassi più dettagliata può essere:

  • meno a digitare, quindi maggiore efficienza di codifica
  • meno da leggere, quindi migliore manutenibilità.

Ora sto parlando solo quando la sintassi meno dettagliata non è in alcun modo complicata o intelligente, solo lo stesso modo riconosciuto di fare, ma in meno caratteri.

Spesso accade quando si vedono costrutti specifici in una lingua che si desidera che il linguaggio che si usa possa avere, ma non lo si è nemmeno realizzato prima. Alcuni esempi in cima alla mia testa:

  • classi interne anonime in Java invece di passare un puntatore a una funzione (via più righe di codice).
  • in Ruby, l'operatore || =, per valutare un'espressione e assegnarlo se valuta false o è nullo. Certo, puoi ottenere la stessa cosa con 3 linee di codice, ma perché?
  • e molti altri ...
0

E se aveste una funzione chiamata costoso (prestazioni) che ha restituito un valore booleano sul lato destro che si desiderava chiamare solo se un'altra condizione era vera (o falsa)? In questo caso il cortocircuito consente di risparmiare molti cicli della CPU. Rende il codice più conciso a causa di un minor numero di istruzioni if ​​annidate. Quindi, per tutti i motivi che hai elencato alla fine della tua domanda.

+0

Sì, questo è uno degli esempi che cito come ovvio motivo. Vedi l'esempio $ model-> valid(). –

+0

Esattamente. Tutti i motivi che citi sono ottimi motivi per utilizzare la valutazione di cortocircuito. – Poindexter

4

Usalo per confondere le persone!

+0

O forse per mantenere il riff (facilmente confuso) dal pasticciare con il codice. – NVRAM

4

Non so PHP e non ho mai visto in corto circuito usato fuori di un caso o mentre condizione in famiglia C di lingue, ma in Perl è molto idiomatica per dire:

open my $filehandle, '<', 'filename' or die "Couldn't open file: $!"; 

One il vantaggio di averlo tutto in un'unica istruzione è la dichiarazione della variabile. Altrimenti dovresti dire:

my $filehandle; 
unless (open $filehandle, '<', 'filename') { 
    die "Couldn't open file: $!"; 
} 

Difficile pretendere che il secondo sia più pulito in tal caso. E sarebbe ancora più divertente in una lingua che non ha unless

+2

Meno cose da digitare rende felici i programmatori. – nos

2

Penso che il tuo esempio sia per il fattore di freschezza. Non c'è motivo di scrivere un codice del genere.

EDIT: Non ho problemi a farlo per ragioni idiomatiche. Se tutti gli altri che usano una lingua usano la valutazione di cortocircuito per creare entità simili a dichiarazioni che tutti capiscono, allora dovresti farlo anche tu.Tuttavia, la mia esperienza è che il codice di quel tipo è raramente scritto nei linguaggi della famiglia C; la forma corretta è solo quella di usare la frase "se" come normale, che separa il condizionale (che presumibilmente non ha effetti collaterali) dalla chiamata di funzione che i controlli condizionali (che presumibilmente ha molti effetti collaterali).

1

correlati a quello che ha detto Dan, mi piacerebbe pensare che tutto dipende dalle convenzioni di ogni linguaggio di programmazione. Non riesco a vedere alcuna differenza, quindi fai tutto ciò che è idiomatico in ogni linguaggio di programmazione. Una cosa che potrebbe fare la differenza che viene in mente è se dovessi fare una serie di controlli, in tal caso lo stile di cortocircuito sarebbe molto più chiaro dell'alternativa se lo stile.

0

La verità è in realtà prestazione. Il cortocircuito viene utilizzato nei compilatori per eliminare il salvataggio del codice morto sulla dimensione del file e sulla velocità di esecuzione. In fase di esecuzione, il cortocircuito non esegue la restante clausola nell'espressione logica se il loro esito non influenza la risposta, accelerando la valutazione della formula. Sto facendo fatica a ricordare un esempio. es

A e B e c

Ci sono due termini in questa formula valutate da sinistra a destra.

se un AND b restituisce FALSE, quindi l'espressione successiva AND c può essere FALSO E VERO o FALSO E FALSO. Entrambi valutano FALSE indipendentemente dal valore di c. Pertanto il compilatore non include AND c nel formato compilato, quindi cortocircuitando il codice.

Per rispondere alla domanda ci sono casi speciali in cui il compilatore non può determinare se l'espressione logica ha un output costante e quindi non cortocircuiterà il codice.

2

operatori di corto circuito può essere utile in due circostanze importanti che non sono ancora stati menzionati:

Caso 1. Supponiamo che tu avessi un puntatore che potrebbe essere o non essere NULL e che volevi controllare che non fosse NULL e che la cosa a cui puntava non fosse 0. Tuttavia, è necessario non dereferenziare il puntatore se è NULL.Senza gli operatori di corto circuito, si dovrebbe fare questo:

if (a != NULL) { 
    if (*a != 0) { 
    ⋮ 
    } 
} 

Tuttavia, gli operatori di corto circuito permettono di scrivere questo in modo più compatto:

if (a != NULL && *a != 0) { 
    ⋮ 
} 

con la certezza che *a sarà non essere valutato se a è NULL.

Caso 2. Se si desidera impostare una variabile per un valore non falso tornato da uno di una serie di funzioni, si può semplicemente fare:

my $file = $user_filename || 
      find_file_in_user_path() || 
      find_file_in_system_path() || 
      $default_filename; 

Questo imposta il valore di $file-$user_filename se presente, o il risultato di find_file_in_user_path(), se è vero o ... così via. Questo è visto forse più spesso in Perl che in C, ma l'ho visto in C.

Ci sono altri usi, inclusi gli esempi piuttosto inventati che citi sopra. Ma sono uno strumento utile e uno che mi è mancato durante la programmazione in linguaggi meno complessi.

+0

Queste sono le "consolidate istruzioni if ​​annidate" che non ricordavo di aver visto in passato o di pensare al codice di esempio. –

0

Pensare in questo modo, se si dispone di una dichiarazione come

if(A AND B) 

è probabile che se A restituisce FALSE avrete sempre e solo desidera valutare B in casi particolari rare. Per questo motivo NON usare una valutazione a corto circuito è fonte di confusione.

La valutazione del cortocircuito rende inoltre più leggibile il codice impedendo la comparsa di un'altra rientranza tra parentesi e le parentesi.