为什么我的优化 IL 在 save 变量中存储相同的值两次?
Why does my optimised IL store the same value in the save variable twice?
源码是一个for循环如下:
public class ForLoop
{
public static void Main()
{
var count = 0;
for (var i = 0; i < 10; i = i++)
{
count++;
}
}
}
我编译它时启用了优化 (csc /o+ ForLoop.cs
),但是 IL 有一个 dup
,后面跟着两个 stloc.1
和一个 ldloc.1
。
.method public hidebysig static void Main() cil managed
{
.entrypoint
// Code size 22 (0x16)
.maxstack 3
.locals init (int32 V_0,
int32 V_1)
IL_0000: ldc.i4.0
IL_0001: stloc.0
IL_0002: ldc.i4.0
IL_0003: stloc.1
IL_0004: br.s IL_0010
IL_0006: ldloc.0
IL_0007: ldc.i4.1
IL_0008: add
IL_0009: stloc.0
IL_000a: ldloc.1
IL_000b: dup
IL_000c: ldc.i4.1
IL_000d: add
IL_000e: stloc.1
IL_000f: stloc.1
IL_0010: ldloc.1
IL_0011: ldc.i4.s 10
IL_0013: blt.s IL_0006
IL_0015: ret
} // end of method ForLoop::Main
IL_000b
的指令在我的 for 循环中复制了 i
变量。然后它加 1,存储结果,所以堆栈上剩下的是我的 i
的原始值,预添加。然后,它再次 存储它并再次加载它。
这感觉不是最佳甚至不正确。
那么它为什么要这么做?
首先你要明白i++
其实就是三个运算:
获取i
的值
将值加一并存储。
将新值推回i
。
其次,你的代码是错误的。您的循环有 i = i++
(而不是通常的简单 i++
),这就是为什么您会看到额外的两个分配。
您正在执行上述三个步骤,并存储 i++
的结果,然后将其推回 i
。
源码是一个for循环如下:
public class ForLoop
{
public static void Main()
{
var count = 0;
for (var i = 0; i < 10; i = i++)
{
count++;
}
}
}
我编译它时启用了优化 (csc /o+ ForLoop.cs
),但是 IL 有一个 dup
,后面跟着两个 stloc.1
和一个 ldloc.1
。
.method public hidebysig static void Main() cil managed
{
.entrypoint
// Code size 22 (0x16)
.maxstack 3
.locals init (int32 V_0,
int32 V_1)
IL_0000: ldc.i4.0
IL_0001: stloc.0
IL_0002: ldc.i4.0
IL_0003: stloc.1
IL_0004: br.s IL_0010
IL_0006: ldloc.0
IL_0007: ldc.i4.1
IL_0008: add
IL_0009: stloc.0
IL_000a: ldloc.1
IL_000b: dup
IL_000c: ldc.i4.1
IL_000d: add
IL_000e: stloc.1
IL_000f: stloc.1
IL_0010: ldloc.1
IL_0011: ldc.i4.s 10
IL_0013: blt.s IL_0006
IL_0015: ret
} // end of method ForLoop::Main
IL_000b
的指令在我的 for 循环中复制了 i
变量。然后它加 1,存储结果,所以堆栈上剩下的是我的 i
的原始值,预添加。然后,它再次 存储它并再次加载它。
这感觉不是最佳甚至不正确。
那么它为什么要这么做?
首先你要明白i++
其实就是三个运算:
获取
i
的值
将值加一并存储。
将新值推回
i
。
其次,你的代码是错误的。您的循环有 i = i++
(而不是通常的简单 i++
),这就是为什么您会看到额外的两个分配。
您正在执行上述三个步骤,并存储 i++
的结果,然后将其推回 i
。