在寻找null check vs捕获NullReferenceException时,我遇到了这个。
捕获空取消引用是CLR可以执行的最昂贵的操作之一,如果您的代码抛出大量NullReferenceExceptions,这可能会对性能产生严重影响。测试nullity并对其做一些其他事情(甚至抛出异常!)是一种更便宜的操作。
以下是我找到问题的链接。 When is handling a null pointer/reference exception preferred over doing a null check?
我想知道如何捕获NullReferenceException比null check和抛出异常更昂贵。
[因为声誉数字不足而无法评论]
答案 0 :(得分:8)
这里的要点不是NullReferenceException
比任何其他例外都贵。抛出异常的代价来自展开堆栈,这更多地取决于调用结构而不是特定异常。我相信文档试图提出的一点是,首先要安全防范异常,而不是在抛出异常时处理异常。
答案 1 :(得分:2)
NullReferenceException
是 硬件异常 ,它首先由Windows Page Fault处理程序进行处理。此操作需要kernel context switch,这可能是非常昂贵的操作,具体取决于基础CPU硬件以及操作系统安全模型。此外,垃圾收集器通常必须暂停某些操作,直到上下文切换完成为止。由于GC为所有线程和应用程序域提供服务,因此任何时候GC暂停使用都会导致潜在的重大性能下降,而这种下降只会在意外的间隔内出现。
通过比较,通过throw
关键字从C#中引发您自己的异常会生成 软件异常 。它们不需要特殊的处理,并且在异常的catch
处理程序是本地的(在同一函数内)的情况下,可以进一步优化,因为不需要额外的展开来发现适当的catch处理程序。这就是MSDN文档建议不要依赖NullReferenceException
的原因。
由于存在太多变量,因此很难给出具体的性能差异值。在最坏的情况下,我可以想象它可能会慢近一个数量级-例如,能够在处理单个硬件异常时抛出并捕获一百个本地软件异常。在实践中,尽管我猜性能比大约在3:1到10:1之间,这取决于CPU,OS,C#CLR和共享Heap / GC的活动线程数。