我一直在考虑嵌套的 try/catch 语句,并开始考虑在哪些条件下(如果有的话)JIT 可以对编译的 IL 进行优化或简化。
为了说明,请考虑以下异常处理程序的功能等效表示。
// Nested try/catch
try
{
try
{
try
{
foo();
}
catch(ExceptionTypeA) { }
}
catch(ExceptionTypeB) { }
}
catch(ExceptionTypeC) { }
// Linear try/catch
try
{
foo();
}
catch(ExceptionTypeA) { }
catch(ExceptionTypeB) { }
catch(ExceptionTypeC) { }
假设嵌套 try 语句的堆栈帧内没有额外的变量引用或函数调用,JIT 能否得出堆栈帧可能折叠为线性示例的结论?
下面的例子怎么样?
void Try<TException>(Action action)
{
try
{
action();
}
catch (TException) { }
}
void Main()
{
Try<ExceptionC>(Try<ExceptionB>(Try<ExceptionA>(foo)));
}
我认为 JIT 没有任何方法可以内联委托调用,因此这个示例不能简化为上一个示例。但是,在foo()
throwing的ExceptionC
情况下,与线性示例相比,此解决方案的性能是否较差?我怀疑从委托调用中拆除堆栈帧会产生额外的成本,即使帧中包含的额外数据很少。