在循环内还是循环外更快地声明变量? [英] Faster to declare variables inside a loop or outside a loop?

查看:76
本文介绍了在循环内还是循环外更快地声明变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在循环内或循环外声明变量是否更快?例如:

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? Why? I assume the latter is faster because it is just reusing the same "pointer" to reference a new value behind the scenes instead of creating a new pointer each iteration, correct? Can someone elaborate?

谢谢

已更新:

编译器足够智能,可以在生成中间语言时优化代码.它将变量声明移到方法的顶部.下面是编译后IL中的声明:

The Compiler is intelligent enough to optimize the code when generating the Intermediate Language. It moves the variable declarations to the top of the method. Below, is the declartions within the 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's the entire 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

推荐答案

我同意凯文(Kevin)的回答,在有意义的地方定义变量.担心优化是否出现以及何时出现,您知道变量声明是问题所在.但是,请考虑以下两段代码

I agree with Kevin's answer, define variables where they have meaning. Worry about optimizations if and when they present themselves and you know that a variable declaration is the issue. However, consider the following two pieces of code

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);
    }
}

及其生成的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 any difference? Those compiler guys, they're smart.

这篇关于在循环内还是循环外更快地声明变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆