[C++语法语义探讨] C++异常会极大地影响效率?

qiezi 2007-06-14
前几天做了个小测试,结果发现C++异常性能比较低。

for(int i=0; i<1000000; i++){
    try{
        //...
    }catch(...){
    }
}

try里面实际上没有异常抛出,这和实际项目中大部分情况相似,异常只有非常少的时候会抛也。

经测试,在C++里面加个try以后性能下降了百多倍,面D语言里面下降非常少,在try里面我只做了几个简单的加法运算而已。

其它语言我没测试过,不过java里面大量使用异常也不会有这么低的效率,所以我想是C++里面才这样吧,目前测试是在g++ 4.1.1下进行的。

另外提一点,上面那个测试中,如果try里面抛出异常,虽然被catch到了,但循环几百万次竟然core dump了,原因未知,只是肯定不是unwind exception,难道是栈溢出?
wzgme 2007-06-15
C++中有一条就是不要轻易使用异常,实在是太复杂了。

你说的是每次循环都被捕获了异常,还是其中某一些特定次啊?

qiezi 2007-06-15
每次捕获,实际上开始是为了测试每个循环中都throw并且catch到,结果程序跑很多循环后就挂掉了,后来才测试性能。
bigpanda 2007-06-15
搭个顺风车问一下有什么资料讲编译器怎么实现exception的没有?

在Win32上是用Windows的SEH,那么又纳闷Windows是怎么实现SEH的。
wzgme 2007-06-15
如果是每次都捕获异常的话,那几百万次捕获后dump掉很正常。一般认为异常不耗费资源,但是次数这么多的捕获,肯定出问题。异常处理有静态查表法和动态注册法。静态查表法,有一个异常堆栈,是放try catch中的东西,主要是放调用处的"开始-结束"地址,我想你的问题是异常堆栈溢出。动态注册法,是依赖编译器的,在编译时候将特定代码写入异常处理的地方,对程序效率有影响。C++异常仅仅是救火队员,不适合过度使用。



对熊猫大哥的问题,我也推荐一把,对于异常的东西很少,这是几篇论文:

Underneath Structured Exceptionse & C++ Exceptions

这是宝蓝的人写的OS/2上的实现,应该和Win上实现比较一致。

Methonds for Handling Exceptions in Object-oriented Programming Languages

丹麦人某大学的硕士论文吧,很好。

Optimizing Away C++ Exception Handling

SCO C++的异常实现讨论。

以上观点主要来自Virtual Machine Design and Implementaion in C/C++,由于手边现在没书,所有记忆可能有出入。






xjx922 2007-06-20
如果真是异常的原因,又必须循环这么多次, 我有个馊主意, 你把变量i定义, 异常处理放在for循环外面,捕捉到异常再 goto回去。或者把for和里面的代码写到小函数里,捕捉到异常再重新调用。
我认为这是算法设计思路的问题。
xjx922 2007-06-20
也许根本不需捕捉异常, 作个简单条件判断就行了。看不到你具体代码, 也许说错了。
qiezi 2007-06-20
xjx922 写道
如果真是异常的原因,又必须循环这么多次, 我有个馊主意, 你把变量i定义, 异常处理放在for循环外面,捕捉到异常再 goto回去。或者把for和里面的代码写到小函数里,捕捉到异常再重新调用。
我认为这是算法设计思路的问题。

没有算法是这样的,这是个简单的测试,我只想知道测试结果说明了什么。
systembug 2007-06-28
Windows下的SEH,需要保存相关的堆栈数据,循环这么多次肯定垮掉。
而且Windows层面的异常处理与Java在根本上的不一样。就像java不用指针一样,如果没有必要不要使用异常。
qiezi 2007-06-28
systembug 写道
Windows下的SEH,需要保存相关的堆栈数据,循环这么多次肯定垮掉。
而且Windows层面的异常处理与Java在根本上的不一样。就像java不用指针一样,如果没有必要不要使用异常。

我是有点奇怪,难道循环结束一次不是会退出一个作用域?下次循环应该是重新进入,堆栈清理不干净?
Global site tag (gtag.js) - Google Analytics