Riciclaggio variabile di tipo di riferimento – una nuova variabile di riferimento ha creato ogni ciclo in un ciclo se dichiarato in esso?

È il seguente:

MyObject myVariable; for(int i = 0; i < objects.Length, i++){ myVariable = objects[i]; // do stuff... } 

più efficiente quindi:

 for(int i = 0; i < objects.Length, i++){ MyObject myVariable = objects[i]; // do stuff... } 

perché una nuova variabile per contenere un riferimento non viene creata ogni volta? (o il compilatore è abbastanza intelligente solo per usare la stessa variabile) ..

(Se viene creata una nuova variabile, viene spostata nell’heap?)

No, le “variabili” esistono quasi interamente per il programmatore. Non stai creando alcun lavoro aggiuntivo in fase di esecuzione dichiarando la variabile all’interno del metodo.

In teoria, il compilatore metterà da parte lo spazio sullo stack quando viene chiamato un metodo per ogni variabile dichiarata in quel metodo. Quindi la presenza di quella variabile nel metodo sarebbe più importante del suo ambito. Nessuno spazio viene allocato sull’heap a meno che non venga utilizzata la new parola chiave.

In pratica, il compilatore può identificare variabili che hanno un raggio così breve da poter essere memorizzate in un registro sulla CPU invece di richiedere spazio nello stack. Per esempio:

 var a = b[c]; a.ToString(); // never access "a" again. 

… sarebbe lo stesso di:

 b[c].ToString(); 

… perché il compilatore riconosce che ha solo bisogno di memorizzare il risultato di b [c] abbastanza a lungo da richiamare un metodo su di esso, quindi può semplicemente usare un registro CPU invece di usare la memoria.

Per questo motivo, dichiarare la propria variabile all’interno del ciclo potrebbe effettivamente indurre il metodo ad allocare meno spazio di stack per la variabile, in base al ansible stream logico successivo. Tuttavia, ciò si traduce in un’enorme micro-ottimizzazione che non ha alcun senso per la maggior parte delle persone a cui interessarsi.

Aggiornare

Poiché alcune persone sembrano ancora pensare che dichiarare una variabile in un ciclo abbia qualche effetto, suppongo di dover fornire una prova. Digitare i seguenti programmi in LINQPad.

 int j; for(int i = 0; i < 5; i++) { j = i; } 

... e...

 for(int i = 0; i < 5; i++) { int j = i; } 

Esegui il codice, quindi vai alla scheda IL per vedere il codice IL generato. È lo stesso per entrambi questi programmi:

 IL_0000: ldc.i4.0 IL_0001: stloc.0 IL_0002: br.s IL_0008 IL_0004: ldloc.0 IL_0005: ldc.i4.1 IL_0006: add IL_0007: stloc.0 IL_0008: ldloc.0 IL_0009: ldc.i4.5 IL_000A: blt.s IL_0004 

Quindi c'è una prova incontrovertibile che questo non farà alcuna differenza in fase di compilazione. Otterrai esattamente la stessa compilazione di IL da entrambi i programmi.

risposta breve, sì.

risposta lunga, sì è più veloce, ma difficilmente percettibile a meno che non venga ripetuta molte volte. 🙂

Non sono sicuro che il compilatore lo ottimizzerà o meno, ne dubito comunque, e se lo fa, bene, dovresti comunque scriverlo come se non fosse, renderlo un habbit.