首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >抛出异常的性能注意事项

抛出异常的性能注意事项
EN

Stack Overflow用户
提问于 2008-08-09 20:01:09
回答 8查看 2.1K关注 0票数 9

我经常遇到以下类型的代码,我想知道这是不是一个好的实践(从性能角度来看):

代码语言:javascript
复制
try
{
    ... // some code
}
catch (Exception ex)
{
    ... // Do something
    throw new CustomException(ex);
}

基本上,程序员所做的就是将异常包含在自定义异常中,然后再次抛出该异常。

这与以下两个在性能上有何不同:

代码语言:javascript
复制
try
{
    ... // some code
}
catch (Exception ex)
{
    .. // Do something
    throw ex;
}

代码语言:javascript
复制
try
{
    ... // some code
}
catch (Exception ex)
{
    .. // Do something
    throw;
}

抛开任何功能或编码最佳实践的论点,这3种方法之间是否存在性能差异?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2008-08-09 21:17:35

@Brad Tutterow

在第一种情况下,异常并没有丢失,而是被传递给了构造函数。不过,我同意你的看法,第二种方法是一个非常糟糕的想法,因为它会丢失堆栈跟踪。当我使用.NET时,我遇到了许多其他程序员这样做的情况,当我需要查看异常的真正原因时,它让我沮丧不已,结果却发现它是从一个巨大的try块重新抛出的,而我现在不知道问题是从哪里开始的。

我也赞同Brad的评论,即你不应该担心性能。这种微观优化是一个可怕的想法。除非您正在讨论在运行了很长时间的for循环的每次迭代中抛出异常,否则您很可能不会因为使用异常而遇到性能问题。

当你的指标表明你需要优化性能时,总是优化性能,然后找到被证明是罪魁祸首的地方。

拥有易于调试的可读代码(IE不隐藏堆栈跟踪)要比让程序运行快一纳秒要好得多。

关于将异常包装到自定义异常中的最后一点注意事项...这可能是一个非常有用的构造,特别是在处理UI时。您可以将每个已知和合理的异常情况包装到某个基本自定义异常(或从所述基本异常扩展而来的异常)中,然后UI就可以捕获这个基本异常。当被捕获时,异常将需要提供向用户显示信息的方法,比如ReadableMessage属性或类似的东西。因此,任何时候UI遗漏异常,都是因为您需要修复一个bug,而每当它捕捉到异常时,它就是一个已知的错误条件,UI可以而且应该正确地处理它。

票数 11
EN

Stack Overflow用户

发布于 2008-08-09 20:58:21

像David一样,我认为第二个和第三个表现更好。但是,这三家公司中有哪一家的表现差到足以花时间去担心它呢?我认为有比性能更大的问题需要担心。

FxCop总是推荐第三种方法,而不是第二种方法,这样原始堆栈跟踪就不会丢失。

编辑:删除了完全错误的内容,Mike好心地指出了这一点。

票数 2
EN

Stack Overflow用户

发布于 2008-08-09 21:01:14

显然,您会受到创建新对象(新异常)的惩罚,因此,正如您对添加到程序中的每一行代码所做的那样,您必须决定更好的异常分类是否会为额外的工作买单。

作为做出这个决定的一条建议,如果你的新对象没有携带关于异常的额外信息,那么你可以忘记构造新的异常。

但是,在其他情况下,拥有异常的层次结构对于您的类的用户来说非常方便。假设您正在实现Facade模式,到目前为止考虑的场景都不是好的:

  1. 不适合将每个异常都作为异常对象引发,因为您正在丢失(可能)有价值的信息
  2. 也不适合引发您捕获的所有类型的对象,因为这样做会导致创建facade

失败

在这种假设的情况下,更好的做法是创建异常类的层次结构,将用户从系统的内部复杂性中抽象出来,允许他们了解所产生的异常类型。

顺便说一句:

我个人不喜欢使用异常(从Exception类派生的类的层次结构)来实现逻辑。如下例所示:

代码语言:javascript
复制
try {
        // something that will raise an exception almost half the time
} catch( InsufficientFunds e) {
        // Inform the customer is broke
} catch( UnknownAccount e ) {
        // Ask for a new account number
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6891

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档