3

我听说人们说异常处理有点昂贵,因为堆栈展开。

我没有得到任何东西,无论我抛出异常以及是否使用“return”,都会发生堆栈展开。那么区别在哪里呢?

例如,如果我遇到无法处理的内存问题 - 唯一的选择是停止该功能,直到我到达应该处理或通知问题的区域。那么我抛出异常的其他选择是什么?

我可以使用“return”而不是抛出异常,但它是一样的。我知道堆栈展开甚至可以返回六个堆栈,但是检查返回值和“返回”结合起来。

欢迎解释。

4

7 回答 7

7

当您使用 return 时,堆栈会无条件地“展开”,这在概念上可以像执行单个“ret”机器代码指令一样简单。在异常下,堆栈展开必须寻找合适的异常处理程序,这是一项复杂得多的任务。异常路径还具有构造和可能复制异常对象的任务,这可能不是微不足道的。

于 2009-12-07T16:36:01.347 回答
3

堆栈展开不同于简单的返回。它还涉及在堆栈的每个较低级别中搜索错误处理程序(catch 块)。这就是使它成为一个繁重的过程的原因。

这就是为什么你应该只在真正例外的情况下使用例外。关于异常处理的警告是针对那些仅仅将异常视为一种在堆栈中向更高层传递数据的方式的人。喜欢做“聪明”编程的人。他们认为这是解决问题的一种聪明方法,但他们却创造了两个他们没有预料到的新问题。

通常,最好使用异常(对于真正的异常情况)而不是返回代码,因为这会使您的代码更易于阅读和维护。例如,哪个更易于阅读和维护?

void MyMethod()
{
    try
    {
        Method1(); 
        Method2();
        Method3();
    }
    catch(SomeException const & e) // edited per Mordachai's suggestion
    {
       // handle SomeException
    }
    catch(SomeOtherException const & e)
    {
       // handle SomeOtherException
    }
}

void MyMethod()
{
    int err;
    err = Method1();
    switch(err)
    {
        case SOMEERRORCODE:
             // handle some error code
             break;
        case SOMEOTHERERRORCODE:
             // handle some other error code
             break;          
    }
    err = Method2();
    switch(err)
    {
        case SOMEERRORCODE:
             // handle some error code
             break;
        case SOMEOTHERERRORCODE:
             // handle some other error code
             break;          
    }
    err = Method3();
    switch(err)
    {
        case SOMEERRORCODE:
             // handle some error code
             break;
        case SOMEOTHERERRORCODE:
             // handle some other error code
             break;          
    }
}
于 2009-12-07T16:40:32.523 回答
2

在发生错误的情况下,错误处理机制的速度并不重要——它们的执行频率应该太低,以免影响整个程序的性能(它们是异常事件)。

当人们谈论异常处理代价高昂时,他们谈论的是当函数完成而不引发异常时它对函数性能的影响。许多编译器将这种开销降低到接近于零 - 但有些平台,特别是游戏机,可用的编译器或硬件不能很好地处理异常。

于 2009-12-07T16:40:24.460 回答
1

首先,传达异常所需的基础设施有一点“成本”。这曾经很重要,很多人选择避免它并完全禁用 RTTI。这些天它是如此微不足道,以至于如果它是一个问题,那么 C++ 对你来说已经太高了;-)

就异常的传播和堆栈展开而言,有额外的成本,但是因为(a)你无论如何都必须展开堆栈,正如你所说的(尽管这并不是真正的成本所在)和(b)你是已经在一个例外路径上,无论如何额外的成本可能永远不会成为问题。

大多数抱怨异常处理成本的人都在思考过去的情况。

于 2009-12-07T16:36:40.487 回答
1

如果您对异常处理对性能的影响感兴趣,最好从C++ 性能技术报告开始阅读(特别是第 5.4 章)。

于 2009-12-07T16:46:49.983 回答
1

我建议在担心程序的性能之前先关注质量、正确性和稳健性。许多用户更喜欢运行缓慢的程序,而不是经常出错的快速程序。

程序运行后,运行分析器并找出大部分时间都花在了哪里。我的拙见是错误处理可能需要更长的时间,因为它发生的频率较低。

于 2009-12-07T18:36:57.733 回答
0

大多数版本的异常处理都会增加一些额外的开销,以帮助编译器处理范围等问题。是一篇有解释的文章。我们正在谈论的开销非常小,几乎不值得担心。

于 2009-12-07T16:35:21.303 回答