我编写了一个简单的程序来检查 IL 的工作原理:
void Main()
{
int a=5;
int b=6;
if (a<b) Console.Write("333");
Console.ReadLine();
}
伊利诺伊:
IL_0000: ldc.i4.5
IL_0001: stloc.0
IL_0002: ldc.i4.6
IL_0003: stloc.1
IL_0004: ldloc.0
IL_0005: ldloc.1
IL_0006: bge.s IL_0012
IL_0008: ldstr "333"
IL_000D: call System.Console.Write
IL_0012: call System.Console.ReadLine
我试图了解实现的效率:
在第 1 行(IL 代码),它将值 5 推入堆栈(4 个字节,即 int32)
在第 #2 行(IL 代码),它从堆栈弹出到局部变量中。
接下来的 2 行也是如此。
然后,它将这些局部变量加载到堆栈上,然后进行评估bge.s
。
问题 #1
为什么他将局部变量加载到堆栈中?这些值已经在堆栈中。但他弹出它们是为了将它们放入局部变量中。这不是浪费吗?
我的意思是,为什么代码不能是这样的:
IL_0000: ldc.i4.5
IL_0001: ldc.i4.6
IL_0002: bge.s IL_0004
IL_0003: ldstr "333"
IL_0004: call System.Console.Write
IL_0005: call System.Console.ReadLine
我的代码示例只有 5 行代码。50,000,000 行代码呢?IL会发出大量额外的代码
问题2
看代码地址:
- IL_0009 地址在哪里?它不应该是顺序的吗?
ps Im 带有优化标志 + 发布模式