Quando la valutazione del corto circuito è errata?


12

Per essere un po 'più chiaro, affermerò che ho trascorso molto tempo con lingue diverse. Ma fino ad ora è stato o lo userà sempre o non lo supporta affatto.

Ora lavoro mi fa iniziare su progetti che richiedono VB.net e vedo che fornisce entrambi i modi in termini di AND e ANDALSO . Il primo non mette in corto circuito e il secondo lo fa.

Quindi questo mi porta a chiedermi perché? Dal momento che la sua configurazione in questo modo sembra implicare che si verifichi abbastanza spesso che si vorrebbe cambiare modalità. Ma non riesco a pensare a nessuna situazione in cui sarebbe un male usare il corto circuito .

So che questo potrebbe benissimo entrare in qualcosa di più di un'opzione, quindi se devo metterlo in un altro posto, dimmi solo dove.

Anche se spero che ci sia almeno una risposta ufficiale, sul perché avere entrambe le opzioni sarebbe meglio che fare sempre Corto circuito , quando è disponibile.



Risposte:


5

Alcuni termini in un'espressione logica possono avere effetti collaterali. A volte è necessario assicurarsi che tutti gli effetti collaterali si verifichino nell'ordine indicato e nessuno di questi venga ignorato ed è il risultato della valutazione che guida la logica:

if not (PushAirPlane(thrust) and TurnAirplane(vector)), SimulateCrash(severity)

In altri casi, non si desidera valutare nessuno dei termini rimanenti se una valutazione precedente restituisce false.

if IsAirborne() and not (PushAirPlane(thrust) and TurnAirplane(vector)), SimulateCrash(severity)

Alcuni hanno / hanno sostenuto che fare affidamento sul comportamento di corto circuito nel secondo esempio è una cattiva forma, ma questo sta entrando nello stile di codifica e nei sistemi di credenze. Ci sono molti pezzi di codice molto buoni al mondo che si basano su quasi tutte le funzionalità fornite da un linguaggio, ed è proprio così.

ANDALSO di VB è nitido e sembra essere un tentativo di rendere la pratica più accettabile.

Come sottolinea JimmyJames nella sua risposta, ci possono essere implicazioni misurabili delle prestazioni nella valutazione del corto circuito. Le lingue che non forniscono il meccanismo, valutano sempre ogni termine dell'espressione, mentre quelle che lo forniscono, possono generare istruzioni di diramazione extra. In entrambi i casi, molto dipende dal numero di passaggi di elaborazione richiesti per valutare ciascuno dei termini e anche dalle architetture di compilatore e CPU. Normalmente non ti interesseresti di queste cose fino a quando non avrai misurato un collo di bottiglia nel codice e non dovrai capire come risolverlo. Qualsiasi regola di do o no relativa al consentire la valutazione di cortocircuito nel codice avrebbe circa le stesse possibilità di causare un codice più lento e l'ottimizzazione precoce può essere una totale perdita di tempo, quindi misurare sempre, quindi ottimizzare.


4
Sebbene sia effettivamente corretto, non è un grande design.
Robert Harvey,

2
@RobertHarvey, non riesco a scrivere un sistema di controllo che non abbia effetti collaterali e non posso controllare correttamente il sistema se non reagisco ai risultati. In altre parole, superalo;).
jwdonahue,

7
No, ma puoi assegnare i risultati di quelle funzioni con effetti collaterali a variabili booleane, controllare quelle variabili nella tua ifcondizione e comunque cortocircuito. Sono d'accordo sul fatto che sia, in un certo senso, una distinzione stilistica, ma ha la virtù di rendere le cose cristalline.
Robert Harvey,

3
@jwdonahue Va bene usare "parole grosse" se il rischio di confusione è basso. Il rischio di confusione e la mancanza di particolari sfumature di un blocco di codice come questo è estremamente elevato e può essere catastrofico per la logica. Non è mai bene far riflettere molto lo sviluppatore della lettura.
jpmc26,

5
"Alcuni termini in un'espressione logica possono avere effetti collaterali" - Sebbene questa affermazione iniziale sia corretta, ritengo che questa risposta non riesca a sottolineare che fare affidamento sugli effetti collaterali è negativo . Molto peggio, infatti, che fare affidamento sulla valutazione del corto circuito per prevenire valutazioni spurie. Che questa risposta suggerisce potrebbe essere una cattiva forma.
aroth,

20

Apparentemente, la tua domanda non riguarda il fatto che il corto circuito sia buono o cattivo in generale, ma sul perché VB.NET fornisce agli operatori con e senza. Con questo in mente, la risposta a

quando la valutazione del corto circuito è errata?

è semplicemente: quando viola la retrocompatibilità .

Ok, ora puoi dire che VB.NET non è molto retrocompatibile con il vecchio VB6 o VBA, comunque almeno alcune parti del linguaggio lo sono. La decisione di Microsoft di mantenere la vecchia semantica AND e OR (senza cortocircuiti) ha reso meno probabile che si verifichi un'enorme categoria di errori durante il porting di vecchi programmi VB su VB.NET.

D'altra parte, i progettisti del linguaggio VB.NET probabilmente hanno condiviso la tua opinione sul fatto che il corto circuito sia una buona cosa. Quando ricordo bene, le prime versioni di pre-release di VB.NET hanno fornito cortocircuito agli operatori AND o OR, ma il feedback degli sviluppatori deve essere stato così male che MS ha ritirato questa decisione prima che apparisse VB.NET 1.0. Quindi i progettisti hanno deciso di implementarlo in termini di nuove parole chiave ANDALSOe ORELSEcome un compromesso tra compatibilità all'indietro e utilità.

IMHO questa è stata una buona decisione. Ho dovuto eseguire il porting di diversi programmi precedenti nell'ultimo decennio, e non dover fare un'analisi di impatto pesante per ogni espressione logica incluso AND e / o OR (giochi di parole) ha reso questo compito molto più semplice ed economico. D'altra parte, ogni volta che devo scrivere una nuova espressione logica in VB.NET, la mia scelta predefinita per gli operatori sono le forme di cortocircuito, questo è quello a cui sono abituato da C, C ++, C # ecc. E mi permette per scrivere diversi modi di dire in forma più concisa (anche se ANDALSO ha bisogno di 4 caratteri in più per scrivere).

Se non sei convinto, ti consiglio di leggere il fantastico articolo di Joel Spolsky sui Martian Headsets , che spiega perché le decisioni di progettazione anticipata nello sviluppo del software non possono essere facilmente revocate dopo che il componente o il linguaggio o l'API in questione hanno raggiunto una base di utenti di una certa dimensione .


Ok, questo si qualifica come un rant e il collegamento a Martian Headsets non sembra essere affatto correlato.
jwdonahue,

6
@jwdonahue: non ho idea del motivo per cui pensi che questo sia un rant, anzi il contrario. E l'articolo su Martian Headsets spiega perché alcune decisioni di progettazione nello sviluppo di software prese diversi decenni fa non possano essere facilmente revocate dopo che il componente o il linguaggio o l'API in questione hanno raggiunto una base di utenti di una certa dimensione. L'analogia non è davvero così difficile da comprendere? VB6 era molto popolare in passato e sono sicuro che ancora centinaia di migliaia di aziende nel mondo hanno app mission-critical in esecuzione su VB6 o VBA.
Doc Brown,

Non vedo proprio come l'articolo "Testate marziane" si adatti davvero. Ciò che è necessario per garantire l'interoperabilità tra X e Y (ad es. Dadi e bulloni) è disporre di standard separati per X e Y, in modo tale che un dado nel caso peggiore possa ospitare un bullone leggermente peggiore di quello specificato e viceversa. Si dovrebbe cercare di scrivere le specifiche in modo da evitare di rendere inutilmente costosi dadi o bulloni o di avere una quantità inutile di pendenza tra dadi e bulloni, ma specificando entrambe le metà separatamente è possibile garantire l'interoperabilità in modo molto più affidabile rispetto al tentativo di avere una specifica servire entrambe le parti.
supercat,

3
@supercat: si tratta di avere già trilioni di miliardi di dadi (o linee di codice VB6) esistenti e in uso, e ora i bulloni (o in questo caso il compilatore VB) saranno sostituiti da una nuova generazione. Se i dadi esistenti si adattano solo a bulloni non metrici, non è economico realizzare solo il sistema metrico dei bulloni più recenti.
Doc Brown,

tl; dr: VB è un dialetto di BASIC, un linguaggio risalente al 1964, e in BASIC l' Andoperazione non mette in corto circuito, né lo fa in SQL (1974), né FORTRAN (1956), né Pascal (1970).
Ben

3

quando la valutazione del cortocircuito è negativa?

Diventano cattivi , non appena inizi a fare affidamento sugli effetti collaterali delle espressioni che prevedi vengano eseguiti nella valutazione di un risultato complessivo booleano.


1

Avvertenza : questo è un po 'esoterico in quanto in quasi tutti i casi, gli sviluppatori non dovrebbero preoccuparsene. Ma ... può esserci un impatto sulle prestazioni a causa della valutazione condizionale in quanto crea ramificazioni nell'esecuzione. Un'operazione non in corto circuito non si ramifica ed è più prevedibile.

Il motivo per cui ciò raramente è importante è che il costo è tipicamente piccolo e di solito compensato dal costo della valutazione della seconda (o terza, ecc.) Condizione. Ciò avrà sempre importanza solo in routine computazionalmente costose quando sono richieste alte prestazioni e potrebbe non essere importante neanche allora.


Penso che finora sia possibile ottimizzare solo un'istruzione logica, alla fine è necessario prendere filiali.
jwdonahue,

@jwdonahue Non capisco. Scusate.
JimmyJames,

Stiamo parlando della logica combinatoria qui. Valutazione del corto circuito o meno, hai uno o più termini che devono essere valutati in base al risultato di un termine precedente. Quindi, è coinvolta la ramificazione.
jwdonahue,

1
@jwdonahue Certo, ma ogni cortocircuito è un ramo aggiuntivo. In alcuni scenari, eseguire due espressioni (ad esempio) è più veloce che controllare il risultato del primo prima di eseguire il secondo, anche se spesso il secondo è irrilevante. Ancora una volta, questo è raramente importante. Il caso che qualcuno mi ha fatto per questo è stato per cose come la moltiplicazione di matrici in cui hai molte semplici valutazioni.
JimmyJames,

1
Ho aggiornato la mia risposta con il merito.
jwdonahue,

0

Pascal non ha definito se AND e OR utilizzino o meno la valutazione del corto circuito, dandoti il ​​peggio di entrambi i mondi.

C e C ++ hanno operazioni bit per bit & e | che in pratica offrono operazioni non in corto circuito. E i compilatori sono liberi di valutare come vogliono se non fa una differenza osservabile.


@Deduplicator: come notato, Pascal non ha definito se AND / OR utilizza la valutazione del corto circuito. Ciò significa "non sapere".
supercat,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.