Is it faster to declare variables inside a loop or outside a loop?

Is it faster to declare variables inside a loop or outside a loop? For example:

' Declaration inside of the loop For each item in items Dim newVariable as String = GetAString() Next ' Declaration outside of the loop Dim newVariable as String = String.Empty For each item in items newVariable = GetAString() Next 

Which one is faster? What for? I guess the latter is faster because it just reuses the same β€œpointer” to refer to the new value behind the scenes instead of creating a new pointer at each iteration, right? Can someone clarify?

thanks

Updated:

The compiler is smart enough to optimize the code when creating an intermediate language. It moves variable declarations to the top of the method. Following are the declarations inside IL after compilation:

  .locals init ([0] string newVariable2, [1] int32 i, [2] string newVariable, [3] int32 V_3, [4] int32 VB$CG$t_i4$S0) 

Here is the whole IL for those interested:

 .method private instance void Form1_Load(object sender, class [mscorlib]System.EventArgs e) cil managed { // Code size 55 (0x37) .maxstack 2 .locals init ([0] string newVariable2, [1] int32 i, [2] string newVariable, [3] int32 V_3, [4] int32 VB$CG$t_i4$S0) IL_0000: nop IL_0001: ldc.i4.0 IL_0002: stloc.1 IL_0003: ldarg.0 IL_0004: callvirt instance string WindowsApplication1.TestVariableDeclaration::getstring() IL_0009: stloc.2 IL_000a: nop IL_000b: ldloc.1 IL_000c: ldc.i4.1 IL_000d: add.ovf IL_000e: stloc.1 IL_000f: ldloc.1 IL_0010: ldc.i4 0x989680 IL_0015: stloc.s VB$CG$t_i4$S0 IL_0017: ldloc.s VB$CG$t_i4$S0 IL_0019: ble.s IL_0003 IL_001b: ldc.i4.0 IL_001c: stloc.3 IL_001d: ldarg.0 IL_001e: callvirt instance string WindowsApplication1.TestVariableDeclaration::getstring() IL_0023: stloc.0 IL_0024: nop IL_0025: ldloc.3 IL_0026: ldc.i4.1 IL_0027: add.ovf IL_0028: stloc.3 IL_0029: ldloc.3 IL_002a: ldc.i4 0x989680 IL_002f: stloc.s VB$CG$t_i4$S0 IL_0031: ldloc.s VB$CG$t_i4$S0 IL_0033: ble.s IL_001d IL_0035: nop IL_0036: ret } // end of method TestVariableDeclaration::Form1_Load 
+6
optimization variables loops declaration
source share
3 answers

I agree with Kevin's answer, I define variables where they make sense. Worry about optimizations if and when they present themselves, and you know that a variable problem is a problem. However, consider the following two code snippets

 void Test1() { foreach (int i in Enumerable.Range(0,10)) { string s = GetString(); Console.WriteLine(s); } } void Test2() { string s; foreach (int i in Enumerable.Range(0,10)) { s = GetString(); Console.WriteLine(s); } } 

And their generated IL:

 Test1: IL_0000: ldc.i4.0 IL_0001: ldc.i4.s 0A IL_0003: call System.Linq.Enumerable.Range IL_0008: callvirt System.Collections.Generic.IEnumerable<System.Int32>.GetEnumerator IL_000D: stloc.1 IL_000E: br.s IL_0024 IL_0010: ldloc.1 IL_0011: callvirt System.Collections.Generic.IEnumerator<System.Int32>.get_Current IL_0016: pop IL_0017: ldarg.0 IL_0018: call UserQuery.GetString IL_001D: stloc.0 IL_001E: ldloc.0 IL_001F: call System.Console.WriteLine IL_0024: ldloc.1 IL_0025: callvirt System.Collections.IEnumerator.MoveNext IL_002A: brtrue.s IL_0010 IL_002C: leave.s IL_0038 IL_002E: ldloc.1 IL_002F: brfalse.s IL_0037 IL_0031: ldloc.1 IL_0032: callvirt System.IDisposable.Dispose IL_0037: endfinally IL_0038: ret Test2: IL_0000: ldc.i4.0 IL_0001: ldc.i4.s 0A IL_0003: call System.Linq.Enumerable.Range IL_0008: callvirt System.Collections.Generic.IEnumerable<System.Int32>.GetEnumerator IL_000D: stloc.1 IL_000E: br.s IL_0024 IL_0010: ldloc.1 IL_0011: callvirt System.Collections.Generic.IEnumerator<System.Int32>.get_Current IL_0016: pop IL_0017: ldarg.0 IL_0018: call UserQuery.GetString IL_001D: stloc.0 IL_001E: ldloc.0 IL_001F: call System.Console.WriteLine IL_0024: ldloc.1 IL_0025: callvirt System.Collections.IEnumerator.MoveNext IL_002A: brtrue.s IL_0010 IL_002C: leave.s IL_0038 IL_002E: ldloc.1 IL_002F: brfalse.s IL_0037 IL_0031: ldloc.1 IL_0032: callvirt System.IDisposable.Dispose IL_0037: endfinally IL_0038: ret 

See the difference? These compilers, they are smart.

+11
source share

None. You still create a new line in each iteration of the loop, so they will be the same. Even if there is one thing, what you accept is incredibly insignificant in a large volume of things.

Declaring the scope of a variable is something that will change, and if you don't need it outside the loop, then you should put it inside.

+4
source share

I could imagine that the optimizer knows that they are the same, and therefore they have the same performance. Perhaps this is not so. You can either check the object code or measure it.

+2
source share

All Articles