【问题标题】:Does the C# compiler optimize out an empty try/catch?C# 编译器是否优化了空的 try/catch?
【发布时间】:2014-04-18 19:26:35
【问题描述】:

在c#中,一个空的try catch块花费了多少时间?

我听说它在 10-55 毫秒之间,但我倾向于零/一,因为编译器会将空的 try catch 替换为无操作占位符。

任何编译器专家可以验证此信息?

【问题讨论】:

  • 我相信你得到这么多反对票的原因是这可能不是问这个特定问题的合适地方......
  • 确保选择一个好的标题,它确实有助于避免负面的初始反应/投票。已经提出的假设和基本问题是“我倾向于零/一,因为编译器将用无操作占位符替换空的 try catch。”,所以请专注于此。
  • 当你说“empty try catch block”时,你的意思是如果你字面上有:try { } catch { }?
  • 这个问题的实际应用是什么?

标签: c# compiler-optimization


【解决方案1】:

如果你通过适当的软件(如 ILspy 或 Reflector)检查编译后的代码,你可以看到空块将被编译器完全删除。

【讨论】:

  • 将来,您需要使用来源等来备份您的答案
  • @Jfabs 检查这个prntscr.com/30ielc (我希望我能正确回答这个问题,因为主题的名称非常可信)
  • 看起来你对我是正确的。感谢您跟进。我建议您编辑您的帖子以包含该屏幕截图作为您声明的证据。
【解决方案2】:

如果当你说“empty try catch block”时,你的意思是字面意思

try
{
}
catch
{
}

那么是的,当构建编译器优化打开(即“发布”模式)时,它不会发出任何 IL 指令。例如:

private void Test()
{
    try
    {
    }
    catch
    {
    }
}

编译为:

IL_0000:  ret

这和空方法一样。

但是,当优化关闭(即“调试”模式)时,它会发出:

IL_0000:  nop         
IL_0001:  nop         
IL_0002:  nop         
IL_0003:  leave.s     IL_000A
IL_0005:  pop         
IL_0006:  nop         
IL_0007:  nop         
IL_0008:  leave.s     IL_000A
IL_000A:  nop         
IL_000B:  ret 

而空方法是:

IL_0000:  nop         
IL_0001:  ret 

在执行JIT编译器时这些IL指令是否被剥离,我不肯定。但这仍然只适用于在没有编译器优化的情况下进行编译,因为在打开它们的情况下,try/catch 在初始编译到 IL 期间被剥离,然后才到达 JIT 编译器。

编辑:我刚刚意识到我可能没有真正回答 问题:

释放模式中,零时间用于空的 try/catch。
调试模式中,空的try/catch 会花费一个非零时间,因为它仍然会发出必要的IL 代码来进行调试/断点,并且需要一些 JIT 编译。但是,这将是一个可以忽略不计的时间。绝对不会接近“10-55 毫秒”。

【讨论】:

    猜你喜欢
    • 2011-03-18
    • 1970-01-01
    • 2013-08-06
    • 1970-01-01
    • 2017-04-21
    • 2015-09-08
    • 1970-01-01
    • 2014-10-14
    • 2015-06-16
    相关资源
    最近更新 更多