在.NET中的方法中拥有但不引发异常的成本

在.NET中的方法中拥有但不引发异常的成本,.net,performance,exception,.net,Performance,Exception,这个问题不是关于在.NET中抛出异常的成本。在前一段时间的一些实验中,如果一个方法在某个执行路径的某个地方包含了一个throw语句,而实际上从未使用过它,那么我看到该方法的性能会发生重大变化。JIT是否以某种方式包装了任何可能在额外代码中引发异常的方法?是的,这是有区别的。x86和x64抖动优化器永远不会内联具有throw语句的方法。这种差异很难量化,因为在内联之后可以进行额外的优化,但每次调用通常只需几纳秒 NET framework代码中常用的一种优化策略是将引发异常的语句放入助手方法中,以

这个问题不是关于在.NET中抛出异常的成本。在前一段时间的一些实验中,如果一个方法在某个执行路径的某个地方包含了一个throw语句,而实际上从未使用过它,那么我看到该方法的性能会发生重大变化。JIT是否以某种方式包装了任何可能在额外代码中引发异常的方法?

是的,这是有区别的。x86和x64抖动优化器永远不会内联具有throw语句的方法。这种差异很难量化,因为在内联之后可以进行额外的优化,但每次调用通常只需几纳秒

NET framework代码中常用的一种优化策略是将引发异常的语句放入助手方法中,以便公共代码路径仍然是内联的。在Math.Abs()方法中可见,例如:

public static int Abs(int value)
{
    if (value >= 0) return value;
    return AbsHelper(value);
}

private static int AbsHelper(int value)
{
    if (value == int.MaxValue) throw new OverflowException(...);
    return -value;
}

这确保了Abs()方法本身是内联的,并且只有负值采用非最佳代码路径。

只有在实际抛出异常时,开销才会很大。我建议您重新测试。不应该,但这是相当可测试的-编写一段代码,调用两个方法,一个有抛出,一个没有抛出,并查看生成的IL。快速测试显示没有显著差异,只要异常没有抛出,您仍然有用于实验的代码吗?可能您遇到了一些奇怪的情况,例如抛出的存在不允许编译器优化某段代码,可能额外的时间被用于测试是否应该抛出异常的条件所消耗,而不仅仅是抛出的存在。如果计时,请确保两个版本都执行条件。