我在MSDN的“处理例外的最佳做法”中偶然发现了这句话:
“使用异常处理更好,因为在正常情况下执行的代码更少”
在是否应该在调用方法之前检查对象的状态或者只是调用方法并捕获异常的上下文中。上述建议是在异常事件很少的情况下。
假设属性检查不会意味着代价高昂的计算,而只是返回一个状态值,与非属性检查相比,非抛出情况下try / catch块的执行成本有多便宜?
我想知道这个建议,因为即使try / catch是免费的或接近免费的,被调用的方法在很多情况下会通过它自己做一堆检查。
答案 0 :(得分:8)
.NET中的异常非常便宜,除非它们被提出。一旦你提出异常,有效成本就会上升很多。
话虽这么说,我强烈建议在这里编程一个最易维护的解决方案,并且如果,并且只有在测量后它被证明是一个问题时才会担心性能。
刚刚返回状态的属性get方法被优化为字段查找,并且几乎是单个操作 - 任何东西通常都会比以后慢。但是,我怀疑异常处理会对你的整体速度产生任何明显的影响,除非它处于一个非常非常紧凑的循环中 - 在这种情况下,整体性能可能不会比你为避免异常处理而引入的检查更糟糕。
答案 1 :(得分:3)
您正在脱离上下文引用该引用。完整的引用是(强调我的):
如果活动非常特殊和 是一个错误(例如意外 文件结束),使用异常处理 更好,因为代码更少 在正常情况下执行。如果 事件经常发生,使用 检查的程序化方法 错误更好。在这种情况下,如果一个 异常发生,异常将 需要更长的时间来处理。
异常处理的开销来自实际捕获异常。如果没有抛出/捕获异常,它相对便宜。
以上引用的逻辑如下:
如果您多次重复操作并且发生异常是不合理的,那么请不要执行检查,请使用异常。您通过不重复每次迭代检查来保存代码周期。
如果操作不反复循环,则检查条件而不是捕获异常。
第一点可以被认为是过早优化的情况,但是有一点是有效的,但是,它应该仅用于特殊情况(没有双关语)。
一般情况下,您需要按照文章的建议进行操作并检查某些状态,而不是依赖于异常处理。
答案 2 :(得分:2)
使用try / catch的另一个好处是它允许您将错误处理集中在一个块中,尤其是当您的函数中有多个可能引发异常的原因时。如果您不需要以不同的方式处理每种情况,那么对所有这些调用都有一次try / catch是有意义的,这样就可以集中处理异常处理。
更重要的是,它允许您使用finally,这对于确保无论是否引发异常都能够正确清理资源非常有用。
答案 3 :(得分:1)
“例外情况适用于特殊情况”,而非正常控制流程。
IME,C#例外可以在例如循环中捕获数千个时,会增加明显的性能损失。
答案 4 :(得分:0)
通常,异常处理机制的设计意图是尝试便宜且投掷费用昂贵。但是,例外肯定比大多数其他操作更昂贵。尽可能避免抛出是最高性能的解决方案,如果您可以采用简单的if语句而不是使用异常,请执行此操作。