【问题标题】:What runtime optimizations does the /optimize flag enable?/optimize 标志启用了哪些运行时优化?
【发布时间】:2015-06-08 13:31:00
【问题描述】:

我一直认为 C# 编译器的 /optimize 标志作用不大。像this one 这样的文章描述了在 IL 中进行的优化相对较少:大多数都归入 JIT。

但是,最近我试图加快一些 CPU 密集型代码的速度(想想很多对数组和字典以及简单数字的迭代),我尝试打开优化只是为了好玩。结果是速度提高了 3 倍。请注意,这纯粹是单击 VS 项目属性页面中的“优化”复选框。切换 DEBUG 和 TRACE 常量对性能没有影响。

虽然小的 IL 优化完全有可能导致这种变化,但这对我来说似乎相当令人惊讶。阅读优化,我在MSDN docs 中发现了这个花絮:

/optimize 还告诉公共语言运行时在 运行时。

我很好奇这意味着什么。这是否意味着 JIT 不对未优化程序集中的代码进行优化?这可以实现哪些优化?

【问题讨论】:

标签: c# performance optimization compiler-optimization jit


【解决方案1】:

在项目的“构建”选项卡中打开“优化代码”选项会做两件事。它将 /optimize+ 选项传递给 C# 编译器,它执行您已经知道的次要 MSIL 优化。但它让 C# 编译器在元数据中发出 [DebuggableAttribute] 属性。你会得到DebuggableAttribute.IsJITOptimizerDisabled 设置为false

抖动使用它来决定是否要启用优化器。所以,是的,您现在已经启用了它,并且获得 3 倍的加速并不罕见。

调试器也起作用,它可以自行强制关闭优化器。相关设置是Tools + Options、Debugging、General、“Suppress JIT optimization”复选框。通常打开,因此您在调试时永远不会获得优化的代码。相当重要的优化代码很难调试。当您想查看优化的机器代码时,您希望关闭该选项。

请记住,您做错了什么。 .NET 项目的默认发布配置始终已选中优化选项。所以你有理由打开它是不合逻辑的。只分析 .NET 项目的发布版本。

【讨论】:

  • 从你所说的来看,听起来代码在优化标志打开或关闭的情况下都可以调试。在这种情况下,为什么要在开发人员在迭代和运行单元测试时使用的调试版本中关闭它?
  • 不,您会失去一些功能,例如无法在 { 花括号 } 上设置断点。那些“微小的变化”。单元测试应该只测试发布版本,没有必要测试与用户机器上运行方式不同的软件。尽管特定于发布的错误并不常见。发生在浮点代码中。
  • 如果您收到故障转储,则优化后的代码很难调试,因为可以优化方法变量等内容。如果您收到无法在本地重现的问题,例如当您的应用程序在无法在开发中复制的环境中与其他方交互时,这将是一个巨大的负担。
猜你喜欢
  • 2016-08-04
  • 1970-01-01
  • 2016-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多