设为首页 加入收藏

TOP

浅谈C++ 异常处理的语义和性能(二)
2015-07-20 17:44:11 来源: 作者: 【 】 浏览:3
Tags:浅谈 异常 处理 义和 性能
如果此函数没有catch,继续往上面函数,重复以上步骤  
VC++的stack unwinding实现大致如此:
?
异常处理逻辑可以转换成一个静态的jump列表(列出上面的四个热点的jump to 地址),和一个stack_unwind()函数(堆栈回滚函数),根据当前的”热点”,通过此列表,动态地跳到异常处里的回滚代码处。
?
综合起来,异常处理在C++中,根据函数的auto变量的分布,必须在每个可能出现异常的函数添加上诉jump列表,导致程序size和工作集明显增加。但是测试表明,如果不出现异常,程序的执行速度的影响是可忽略的(仅仅需要保持热点位置),TestMyAppObject的测试结果选择异常处理(但不出异常)反而比选择不支持异常处理稍快。?
?
出现异常后,TestMyAppObject的测试结果表明,程序速度的影响可以在10%~15%以上。但是我的测试还没有加rethrow 获者其它异常处理逻辑,仅仅俘获而已。
?
另一个有趣的问题是,函数中auto变量的分布,对“热点列表”size的影响, 热点太多,会导致热点列表变得很大,所以如果可能,尽量把auto变量放在顶端:
?
X a, b;
?
Y c,d;
?
而不是
?
X a;
?
// do something (1)
?
X b;
?
// do something else (2)
?
Y c;
?
// do yet something else (3)
?
Y d;
?
因为第一种分布只有一个热点(假设constructor 不会throw)。而第二种分布至少有三个热点。
?
测试结果
测试上述TestMyAppObject函数,循环1000次的结果:?
?
传值0,使line4不出现异常(C++ throw),时间是0.802秒。
? ? ? ? 传值1,使line4出现除零异常,时间是0.832秒。
?
传值2,使line4出现异常(C++ throw),测试1000次测试,时间是1.043秒。
这个结果我有下列观察:
?
C++ throw的代价明显高于windows SEH。C++ throw 异常在上述测试的时间比不出现异常增加近20%。但是如果我们throw简单的primitive 值,速度可能增快(读者可以自己测试)。
除零异常在这里和无异常速度接近,但是考虑到本测试的简单性,和实际应用中try-catch可能纵跨多个函数,会线性增加stack-unwinding的代价。所以我认为,实际结果中,如果异常出现后出现性能10%~15%下降是正常的。
另外要考虑的是OS和编译版本。VC++的异常处理比前面版本的性能大大提高了。?
总结
异常处理是C++中具有重要附加值的语言构造,为安全可靠的应用程序提供了基石。
?
但是它也同时具有时空两方面的代价(trade off),我们在应用时要清楚这个方面。异常应该在“异常时”用 (好像是废话,其实是设计思想和模式的重要一环),不要把它当作方便的“控制构造 control construct”来用。如果应用容许,也要尽可能减少“热点”,减小热点列表。
?
?
首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇grunt学习笔记(适用初学者) 下一篇LeetCode 第九题, Palindrome Num..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·C++中智能指针的性能 (2025-12-25 03:49:29)
·如何用智能指针实现c (2025-12-25 03:49:27)
·如何在 C 语言中管理 (2025-12-25 03:20:14)
·C语言和内存管理有什 (2025-12-25 03:20:11)
·为什么C语言从不被淘 (2025-12-25 03:20:08)