基于随机互联网评论,我一直认为C#编译器对IL 进行简单优化(删除always-true if语句,简单内联等),然后是JIT执行真实,复杂的优化。
仅作为一个例子,在the documentation for the /optimize
compiler flag上,它说
/ optimize选项启用或禁用编译器执行的优化,以使输出文件更小,更快,更高效。
这意味着至少某些优化由语言编译器应用。
然而,玩Try Roslyn,这似乎不正确。看起来C#编译器根本就没有优化。
输入:
bool y = true;
if (y)
Console.WriteLine("yo");
if (true)
{
Console.WriteLine("yo");
}
输入:
static void DoNothing() { }
static void Main(string[] args)
{
DoNothing();
Console.WriteLine("Hello world!");
}
private static void DoNothing()
{
}
private static void Main(string[] args)
{
NormalProgram.DoNothing();
Console.WriteLine("Hello world!");
}
输入:
try
{
throw new Exception();
}
catch (Exception)
{
Console.WriteLine("Hello world!");
}
try
{
throw new Exception();
}
catch (Exception)
{
Console.WriteLine("Hello world!");
}
正如您所看到的,C#语言编译器似乎根本没有进行优化。
这是真的吗?如果是这样,为什么文档声称/optimize
会使您的可执行文件变小?
答案 0 :(得分:3)
我能想到的唯一优化是C#编译器执行的实际操作使用反编译器是添加一个空的静态构造函数。
它们通常非常无趣,只是更紧凑的IL。你只能在看IL的时候看到它们,一个体面的反编译器不会显示它。未经优化的代码具有递归良好编译器的代码生成器的典型工件,冗余存储紧接着加载相同变量,分支到下一个地址。优化器知道如何消除它们。标准示例是为了帮助调试而发出的NOP,它们允许您在花括号上设置断点。由优化器删除。
没有什么可以提供轻松的可观察的性能提升,尽管你可能很幸运,更紧凑的IL恰好让抖动优化器有足够的时间来消除关键的内存存储。这种情况不会经常发生。
答案 1 :(得分:1)
/optimize
标志对编译器说#34;嘿,这个代码试图尽可能优化"但这并不意味着那是圣杯旗帜优化
/optimize
标志执行许多操作,例如删除未使用的变量,替换已声明的变量但未使用(例如您的示例),代码中的总数(例如int a = 2+2;
变为int a = 4;
以及许多其他事项cand find here