Controlla se la variabile non è nulla prima di impostare su null

5

A un nostro team piace scrivere codice come questo (C #):

if (_someVar != null)
{
    _someVar = null;
}

Piuttosto che semplicemente:

_someVar = null;

Non ho mai usato il primo dato che ho sempre pensato che non fosse necessario, specialmente in un linguaggio come .Net. Prima di entrare in un dibattito con loro volevo sapere se c'è qualche vantaggio nel fare questo controllo? Questa persona proviene da uno sfondo di Java, quindi mi sono chiesto se fosse un'abitudine che hanno tenuto da quella.

    
posta Andrew Stephens 04.08.2017 - 16:45
fonte

5 risposte

10
  1. Se _someVar è una proprietà anziché una variabile,

    • e l'impostazione ha effetti collaterali, che potrebbero essere codice funzionalmente diverso.
    • e impostarlo è molto più impegnativo di leggerlo, testare e cogliere l'occasione con una previsione errata delle branch, potrebbe essere più efficiente.
  2. Se _someVar è nella memoria del dispositivo (nel qual caso dovrebbe essere volatile , e ciò non si applica a .Net ), si applica il punto sulle proprietà con effetti collaterali.

  3. Se _someVar si trova nella memoria di accesso condivisa, così facendo si evita di annullare la condivisione della riga della cache contenente, che eviterebbe il bounce della cache.
    Se è previsto che sia già null , non dovrebbe esserci nemmeno troppo errata interpretazione delle branche.

  4. Se _someVar si trova in una pagina di memoria raramente modificata, si eviterà di sporcare la pagina, preservando la larghezza di banda del disco utilizzata per riscrivere le pagine modificate, sia per prepararsi che per liberare una pagina.

Probabilmente non trarrai mai alcun beneficio dal prendere in considerazione nessuno di questi scenari.
Se uno si applica, dovrebbe esserci un commento esplicito che lo giustifichi in quanto è troppo raro.
Quasi sempre, è solo un'offuscamento e una pessimizzazione e dovrebbe essere catturato nella revisione del codice.

    
risposta data 05.08.2017 - 00:26
fonte
7

Fare questo come ovvio per tutti i casi in cui una variabile viene impostata su null sembra sciocca, poiché sono certo che non ha assolutamente alcuno scopo il 99,9% delle volte. Dopo che il codice è stato eseguito, lo stato della variabile sarà identico in entrambi gli scenari. Potrebbe esserci una differenza sotto il sub-nanosecondo se è necessario eseguire questo un miliardo di volte, poiché le letture della CPU sono più veloci delle scritture (senza alcuna memorizzazione nella cache, previsione delle branch o operazioni di riordino del tutto, le scritture sono due volte più lente, ma questo non significa che finiranno con il doppio del rallentamento una volta aggiunti tutti quei meccanismi, anche la maggiore dimensione della base di codice e il working set potrebbero compensare eventuali guadagni). Ma non c'è alcuna differenza funzionale.

È concepibile che potrebbe essere una differenza funzionale in rari casi di eccezione, ad es. se la variabile è contrassegnata volatile . In questo caso, il controllo Null creerà una barriera di memoria di lettura e salterà l'impostazione di una barriera di memoria di scrittura se è già nullo. Non riesco a immaginare nessuno scopo legittimo, ma è possibile che qualche enigmatico abbia trovato una differenza molto sottile in alcuni comportamenti di basso livello, ad es. il controllo nullo può impedire a un set nullo ridondante di interferire con la coda di scrittura della CPU, risolvendo problemi oscuri di cui non ho mai sentito parlare.

Sono una specie di spitballing qui, ma ho pensato che potreste essere interessati a questa possibilità molto stretta. Di sicuro non ho mai verificato nulla prima di averlo impostato, né qualcuno che conosco, né alcun esempio in alcun articolo della Knowledge Base che abbia mai letto.

Un altro motivo interessante che un commentatore ha notato è che potrebbe essere utile essere in grado di impostare un punto di interruzione che si attiva solo quando viene rilasciato il riferimento. Se segui lo schema e inserisci un punto di interruzione nel compito, funzionerà in questo modo.

Il mio pensiero finale è forse è un residuo dei giorni in cui facevamo riferimento al conteggio quando rilasciavamo gli oggetti. Con GC, ovviamente, tutti questi modelli non sono aggiornati ora.

Forse non si avvicina a questo come a un dibattito ma a un'opportunità di apprendimento. Chiedi loro perché lo fanno. Sono davvero curioso di cosa diranno.

    
risposta data 04.08.2017 - 23:07
fonte
2

Fidati del compilatore .

Se il controllo null ha senso, lascia che il compilatore lo inserisca. Gli scrittori di compilatori trascorrono giorni a capire tali micro-ottimizzazioni.

Scrivi codice leggibile

_someVar = null ha la proprietà piacevole che è immediatamente chiaro quale sia lo stato finale. Indipendentemente dallo stato precedente, lo stato finale è null .

    
risposta data 10.08.2017 - 17:35
fonte
1

Non ha senso. Il risparmio di tempo sarebbe trascurabile.

Non avrebbe senso anche nel caso in cui dovessimo assegnare un oggetto, poiché l'oggetto avrebbe bisogno di essere già istanziato per poter eseguire il confronto, quindi nessun overhead di creazione dell'oggetto sarebbe stato salvato.

if ( ! _someVar.equals(myObj))
{
    _someVar = myObj;
}

Avrebbe senso solo se c'era qualcos'altro oltre all'assegnazione nulla da fare, perché runnign doThis () ha qualche costo o se qualche motivo non si desidera eseguirlo due volte:

if (_someVar != null)
{
    _someVar = null;
    doThis();
}
    
risposta data 04.08.2017 - 22:04
fonte
0

Riesco a vedere un caso legittimo, anche se raro, per questo:

Come altri hanno già detto, supponiamo che _someVar sia una proprietà. È stato criticato il fatto che se gli effetti collaterali rendono costoso che hai un problema peggiore, ma non penso che sia sempre il caso.

Considera una funzione che mantiene una sorta di audit trail. Ora scrivere è legittimamente costoso (forse molto costoso - scrivere il log di controllo su disco) senza che si tratti di effetti collaterali irragionevoli.

    
risposta data 05.08.2017 - 05:47
fonte

Leggi altre domande sui tag