C#语言编译器是否自己执行任何实际优化?

Blu*_*eft 10 .net c# compiler-optimization

基于随机的Internet评论,我一直认为C#编译器对IL进行简单的优化(删除always-true if语句,简单的内联等),然后JIT执行真正的复杂优化.

举个例子,在编译器标志的文档中/optimize,它说

/ optimize选项启用或禁用编译器执行的优化,以使输出文件更小,更快,更高效.

这意味着语言编译器至少应用了一些优化.


然而,玩Try Roslyn,这似乎不是真的.看起来C#编译器根本就没有优化.

例子

输入:

bool y = true;
if (y)
    Console.WriteLine("yo");
Run Code Online (Sandbox Code Playgroud)

反编译输出:

if (true)
{
    Console.WriteLine("yo");
}
Run Code Online (Sandbox Code Playgroud)

输入:

static void DoNothing() { }

static void Main(string[] args)
{
    DoNothing();
    Console.WriteLine("Hello world!");
}
Run Code Online (Sandbox Code Playgroud)

反编译输出:

private static void DoNothing()
{
}
private static void Main(string[] args)
{
    NormalProgram.DoNothing();
    Console.WriteLine("Hello world!");
}
Run Code Online (Sandbox Code Playgroud)

输入:

try
{
    throw new Exception();
}
catch (Exception)
{
    Console.WriteLine("Hello world!");
}
Run Code Online (Sandbox Code Playgroud)

反编译输出:

try
{
    throw new Exception();
}
catch (Exception)
{
    Console.WriteLine("Hello world!");
}
Run Code Online (Sandbox Code Playgroud)

如您所见,C#语言编译器似乎根本没有进行优化.

这是真的?如果是这样,为什么文档声称/optimize会使您的可执行文件变小?

Han*_*ant 3

我能想到的 C# 编译器执行的、您可以通过反编译器实际看到的唯一优化是添加一个空的静态构造函数。

它们通常相当无趣,只是 IL 更紧凑。你只能在查看 IL 时看到它们,好的反编译器不会显示它们。未优化的代码具有递归体面编译器的代码生成器的典型工件,冗余存储紧随其后的是同一变量的加载,分支到下一个地址。优化器知道如何消除它们。标准示例是发出以帮助调试的 NOP,它们允许您在花括号上设置断点。被优化器删除。

尽管您可能很幸运,更紧凑的 IL 恰好为抖动优化器提供了足够的时间来消除关键内存存储,但没有什么可以提供容易观察到的性能改进。这种情况并不经常发生。