Domanda

Ho un'istruzione if con due condizioni (separate da un operatore OR), una delle condizioni copre il 70% delle situazioni e richiede molto meno tempo per essere elaborata/eseguita rispetto alla seconda condizione, quindi nell'interesse della velocità voglio solo la seconda condizione da elaborare se la prima condizione risulta falsa.

se ordino le condizioni in modo che la prima condizione (quella più veloce) appaia per prima nell'istruzione if - nelle occasioni in cui questa condizione è soddisfatta e valuta vera, viene elaborata anche la seconda condizione?

if ( (condition1) | (condition2) ){
  // do this
}

o dovrei nidificare due istruzioni if ​​per verificare solo la seconda condizione se la prima risulta falsa?

if (condition1){
  // do this
}else if (condition2){
  // do this
}

Sto lavorando in PHP, tuttavia, presumo che questo possa essere indipendente dalla lingua.

È stato utile?

Soluzione

Per C, C++, C#, Java e altri linguaggi .NET le espressioni booleane sono ottimizzate in modo che non appena si sa abbastanza non venga valutato nient'altro.

Un vecchio trucco per creare codice offuscato era usarlo per creare istruzioni if, come:

a || b();

se "a" è vera, "b()" non verrebbe mai valutato, quindi possiamo riscriverlo in:

if(!a)
    b();

e allo stesso modo:

a && b();

potrebbe diventare

if(a)
    b();

notare che che questo è valido solo per il || e & operatore.I due operatori | e & è bit per bit or, e e, rispettivamente, e quindi non sono "ottimizzati".

MODIFICARE:Come accennato da altri, cercare di ottimizzare il codice utilizzando la logica di cortocircuito è molto raramente un tempo ben speso.

Innanzitutto puntate sulla chiarezza, sia perché è più facile da leggere che da comprendere.Inoltre, se si tenta di essere troppo intelligenti, un semplice riordino dei termini potrebbe portare a comportamenti molto diversi senza alcuna ragione apparente.

In secondo luogo, procedere all’ottimizzazione, ma solo dopo aver individuato tempistiche e profilazione.Troppi sviluppatori eseguono ottimizzazioni premature senza profilazione.La maggior parte delle volte è completamente inutile.

Altri suggerimenti

Praticamente ogni lingua esegue una valutazione di cortocircuito.Ciò significa che la seconda condizione viene valutata solo se è assolutamente necessaria.Affinché funzioni, la maggior parte delle lingue utilizza la doppia pipe, ||, non quella singola, |.

Vedere http://en.wikipedia.org/wiki/Short-circuit_evaluation

In C, C++ e Java, l'affermazione:

if (condition1 | condition2) {
  ...
}

valuterà entrambe le condizioni ogni volta e sarà vera solo se l'intera espressione è vera.

La dichiarazione:


if (condition1 || condition2) {
  ...
}

valuterà condition2 solo se condition1 è falso.La differenza è significativa se condizione2 è una funzione o un'altra espressione con un effetto collaterale.

Non c'è tuttavia alcuna differenza tra il || caso e il if/else caso.

Ultimamente ho visto molte di queste domande: ottimizzazione all'ennesima potenza.

Penso che abbia senso in determinate circostanze:

  1. La condizione di calcolo 2 non è un'operazione a tempo costante
  2. Lo chiedi esclusivamente per scopi didattici: vuoi sapere come funziona la lingua, non per salvarci.

In altri casi, preoccuparsi del modo "più veloce" per ripetere o controllare un condizionale è sciocco.Invece di scrivere test che richiedono milioni di prove per vedere differenze registrabili (ma insignificanti), concentrati sulla chiarezza.

Quando qualcun altro (potresti essere tu!) prenderà in mano questo codice tra un mese o un anno, la cosa più importante sarà la chiarezza.

In questo caso, il tuo primo esempio è più breve, più chiaro e non richiede di ripeterti.

Secondo Questo articolo PHP esegue una valutazione di cortocircuito, il che significa che se la prima condizione è soddisfatta, la seconda non viene nemmeno valutata.È abbastanza facile testare anche (dall'articolo):

<?php
/* ch06ex07 – shows no output because of short circuit evaluation */

if (true || $intVal = 5) // short circuits after true
{

echo $intVal; // will be empty because the assignment never took place
}

?>

Il cortocircuito non è per l'ottimizzazione.Il suo scopo principale è evitare di chiamare codice che non funzionerà, ma che risulterà in un test leggibile.Esempio:

if (i < array.size() && array[i]==foo) ...

Tieni presente che array[i] potrebbe benissimo subire una violazione di accesso se i è fuori portata e mandare in crash il programma.Quindi questo programma dipende sicuramente dal cortocircuito della valutazione!

Credo che questo sia il motivo per cui si scrivono espressioni in questo modo molto più spesso che per motivi di ottimizzazione.

Sebbene l'utilizzo del cortocircuito a fini di ottimizzazione sia spesso eccessivo, esistono sicuramente altri motivi convincenti per utilizzarlo.Uno di questi esempi (in C++) è il seguente:

if( pObj != NULL && *pObj == "username" ) {
    // Do something...
}

In questo caso si fa affidamento sul cortocircuito per garantire ciò pObj è stato assegnato prima di dereferenziarlo.Questo è molto più conciso dell'annidamento if dichiarazioni.

Dato che questo è taggato indipendentemente dalla lingua, interverrò.Almeno per Perl è sufficiente la prima opzione, non ho familiarità con PHP.Viene valutato da sinistra a destra e si interrompe non appena la condizione viene soddisfatta.

Nella maggior parte dei linguaggi con un'ottimizzazione decente, il primo funzionerà perfettamente.

IL | è un operatore bit a bit in PHP.Non significa $a OR $b, esattamente.Ti consigliamo di utilizzare il doppio tubo.E sì, come accennato, PHP esegue la valutazione in cortocircuito.In modo simile, se la prima condizione di an && clausola restituisce false, PHP non valuta nemmeno il resto della clausola.

VB.net ha due meravigliose espressioni chiamate "OrElse" e "AndAlso"

OrElse si cortocircuiterà la prima volta che raggiunge una valutazione True ed eseguirà il codice desiderato.

If FirstName = "Luke" OrElse FirstName = "Darth" Then
   Console.Writeline "Greetings Exalted One!"
End If

AndAlso si cortocircuiterà la prima volta che si tratta di una valutazione False e non valuterà il codice all'interno del blocco.

If FirstName = "Luke" AndAlso LastName = "Skywalker" Then
   Console.Writeline "You are the one and only."
End If

Trovo entrambi utili.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top