gpt4 book ai didi

.net - 在循环内或循环外声明变量更快?

转载 作者:行者123 更新时间:2023-12-02 12:47:25 27 4
gpt4 key购买 nike

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

' 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

哪个更快?为什么?我认为后者更快,因为它只是重用相同的“指针”在幕后引用新值,而不是每次迭代创建一个新指针,对吗?有人可以详细说明一下吗?

谢谢

更新:

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

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

以下是感兴趣的人的完整 IL:

.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

最佳答案

我同意凯文的回答,定义变量有意义。如果优化出现并且您知道变量声明是问题所在,请担心优化。但是,请考虑以下两段代码

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

看出什么不同了吗?那些编译器家伙,他们很聪明。

关于.net - 在循环内或循环外声明变量更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3917724/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com