C#编译器是否优化了空的try / catch?

时间:2014-03-13 19:38:56

标签: c# compiler-optimization

在c#中,空的try catch块消耗了多少时间?

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

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

2 个答案:

答案 0 :(得分:5)

如果你说“空尝试捕获块”,你的意思是字面意思

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指令,我不是肯定的。但是这仍然只适用于没有编译器优化的编译,因为在它们到达JIT编译器之前,在初始编译到IL之前,try / catch被剥离了。

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

发布模式中,空的try / catch消耗零时间 在调试模式中,空的try / catch会消耗非零时间,因为它仍会为调试/断点目的发出必要的IL代码,并且需要某些 JIT编译。但是,这将是可忽略的小时间量。绝对没有“10-55毫秒”附近。

答案 1 :(得分:2)

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

ILSpy image