在发布模式下,开销是最小的。
除非你要以递归方式使用异常来进行流程控制(例如,非局部退出),否则我怀疑你不会注意到差异。
关于捕获异常所涉及到的性能,这里有一点需要注意。
当执行路径进入`try`块时,没有任何神奇的事情发生。没有`try`指令,也没有与进入或退出try块相关的成本。有关尝试块的信息存储在方法的元数据中,并且每当引发异常时都会在运行时使用此元数据。执行引擎沿着堆栈向下走,寻找包含在try块中的第一个调用。与异常处理相关的任何开销仅在抛出异常时发生。
当编写供他人使用的类/函数时,似乎很难确定何时适用异常。BCL 的一些有用部分我不得不放弃并选择 pinvoke,因为它们会抛出异常而不是返回错误。对于某些情况,您可以解决问题,但对于其他情况,例如 System.Management 和 Performance Counters,存在需要在其中执行循环的用法,BCL 经常会抛出异常。
如果您正在编写库,并且有可能您的函数可能在循环中使用,并且存在大量迭代的潜力,请使用 Try.. 模式或其他方式来除了异常之外暴露错误。即使如此,在共享环境中由许多进程使用时,很难说您的函数将被调用多少次。
在我的代码中,只有在事情非常特殊以至于必须查看堆栈跟踪并查看出错原因并进行修复时才会引发异常。因此,我基本上已经重新编写了 BCL 的某些部分,以使用基于 Try.. 模式的错误处理而不是异常。