"/optimize" C#编译器关键字的用途是什么?

10

是否有一个完整的关于/optimize C#编译器选项所做的优化列表可以在任何地方找到?

编辑: 为什么默认情况下该选项被禁用? 在现实世界的应用中使用它是值得的吗? - 它只在调试配置中默认禁用,在发布配置中启用。


2
我将于6月11日在我的博客上回答这个(经常被问到的!)问题。 - Eric Lippert
2
http://blogs.msdn.com/ericlippert/archive/2009/06/11/what-does-the-optimize-switch-do.aspx - Eric Lippert
3个回答

8

Scott Hanselman有一篇博客文章,展示了/optimize(在发布构建中启用)的一些示例。

总的来说:/optimize会做很多事情,没有确切的数字或定义,但其中一个更明显的是方法内联(如果您有一个调用B()和C()的A()方法,编译器可能会“跳过”B和C,直接从A到D),这可能会导致发布版本中出现“奇怪”的调用堆栈。


2

在调试版本中,默认情况下它是禁用的。而在发布版本中,则启用了该选项。

启用此开关绝对是值得的,因为编译器根据您的代码类型进行了许多微调和优化。 例如:跳过冗余的初始化、永远不会改变的比较等。

注意:如果您打开优化,可能会遇到一些调试困难,因为您的代码和生成的IL代码可能不匹配。这就是它仅在发布版本中启用的原因。


哦,好的。我会更新问题。但我仍然想知道确切(或足够完整)的优化列表是什么...... - Massimiliano

2

引用自MSDN页面

/optimize选项使编译器能够对生成的输出文件进行优化,从而使程序更小、更快、更高效。

换句话说,它确切地做了你想要的事情——优化在.NET虚拟机上执行的编译后的CIL(Common Intermediate Language)代码。你不必担心具体的优化方式是什么,可以肯定的是它们很多,在某些情况下可能相当复杂。如果你真的对它所做的事情感兴趣,可以研究一下Mono C# Compiler(我怀疑MS C#的细节并未公开)。

默认情况下,在“Debug”配置中禁用优化的原因是它会使某些调试功能无法使用。以下是一些值得注意的功能:

  • 最重要的是,禁用编辑和继续功能,即无法在执行过程中修改代码。
  • 打断点经常会导致错误的代码行被高亮显示(通常是期望之后的一个代码行)。
  • 未使用的本地变量实际上并没有被赋值或甚至声明。

事实上,优化的默认选项永远不应该被更改。在调试时关闭该选项非常有用,在发布模式下开启它同样是明智的选择。


我不担心优化,我只想知道它们是什么 :-) 我也想点赞你的努力,但有一件事阻止了我:".NET VM" :-) - Massimiliano
即使术语并不精确,将CLR称为VM在概念上也不完全错误。您有伪机器码CIL,在不存在但由CLR模拟的机器上运行。可以认为,CLR JIT代码的事实是实现细节,尽管它承载着巨大(主要是有益的)后果。 - Rui Craveiro
@Rui:谢谢……我知道它在技术上是CLR,但出于许多争论的缘故,我倾向于交替使用这些术语。不过你的解释确实澄清了一些事情。值得注意的是,Java CLR 的等效物被明确称为 VM(JVM),我甚至认为微软有时也将其称为 VM,因此该术语在这个上下文中相当常用。 - Noldorin
Java 的虚拟机实现了相当长一段时间的字节码解释器。.NET 从未拥有过这样的结构,因此 MSIL 从未被“执行”,只是编译。 - Massimiliano
2
@Yacoder:运行时编译与AOT编译不同。IL字节码是中间语言,因此CLR是一种经典的虚拟机,可以抽象出底层硬件。我希望人们不要在语义上纠缠不清,特别是当他们是错误的时候。 - Alexandru Nedelcu
从某种意义上说,任何语言都会在硬件上创建一个抽象层,从而创建一个虚拟机。这就是为什么我不会对答案进行贬低。它并没有错。只是在描述CLR的工作方式时,并不是最好的方式,特别是与经典的Java VM相比,后者解释字节码并且没有JIT编译器。 - Massimiliano

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接