如何优化C#编译器?

时间:2016-03-15 11:52:50

标签: c# .net optimization compiler-optimization cil

此代码的IL代码(使用https://dotnetfiddle.net生成):

public class Program
{
    public static void Main()
    {
        int i = 10;
        if (i < 4)
            Console.WriteLine("Hello World");
    }
}

包含ldstr&#34; Hello World&#34;。

编译器是否应该知道Console.WriteLine永远不会被执行?

此代码的IL代码:

public class Program
{
    public static void Main()
    {
        if (10 < 4)
            Console.WriteLine("Hello World");
    }
}

不包含ldstr命令。

现在我很困惑.. .NET编译器真的很蠢吗? 两个示例的C#/ IL代码完全相同:没有。但是第一个例子的IL代码比另一个大。难道不是一个好的编译器只是调用构造函数而什么也不做。?

编辑:

是的,我已经阅读了this,但我不是在谈论其他生成的本地人。

如果i是属性或公共变量,则可以从另一个线程修改它。但i仅存在于Main()...

3 个答案:

答案 0 :(得分:8)

以下是您的代码段的x64反汇编:

00007FF7C6083E0E  add         byte ptr [rax],al  
--- C:\Dev\Temp\Test\ConsoleApp\ConsoleApp\Program.cs --------------------------
            int i = 10;
00007FF7C6083E10  ret  
--- No source file -------------------------------------------------------------

这意味着,JIT执行了死代码消除(ret = 返回Main函数只是立即退出)。

编译器只执行一些基本的优化,但大部分都留给JIT,以优化它运行的平台。

虽然我同意编译器肯定可以在这种情况下执行此优化,因为它与平台无关。

答案 1 :(得分:3)

在我看来,编译器按预期运行。编译器通常只计算常量和常量表达式,因为它们的值在编译时是已知的。变量&#34; i&#34;在你的例子和表达式&#34; i&lt; 4&#34;在运行时进行评估,这就是编译器在这种情况下不优化代码的原因。

答案 2 :(得分:-2)

我也认为这不应该是调试器的责任。虽然您的样本中的所有内容都很明显,但每行都会在计算值时显示累积影响,这是一项巨大的工作量,将其视为计算可用的总棋舍数。 (国际象棋中有数十亿的动作比宇宙中的所有恒星都多。)