了解C++异常处理的系统开支

为了在运行时处理异常,程序要记录大量的信息。无论执行到什么地方,程序都必须能够识别出如果在此处抛出异常的话,将要被释放哪一个对象;程序必须知道每一个入口点,以便从try块中退出;对于每一个try块,他们都必须跟踪与其相关的catch子句以及这些catch子句能够捕获的异常类型。这种信息的记录不是没有代价的。确保程序满足异常规格不需要运行时的比较(runtime comparisons),而且当异常被抛出时也不用额外的开销来释放相关的对象和匹配正确的catch字句。但是异常处理确是有代价的,即使你没有使用try,throw或catch关键字,你同样得付出一些代价。

让我们先从你不使用任何异常处理特性也要付出的代价谈起。你需要空间建立数据结构来跟踪对象是否被完全构造(constructed)(参加条款10),你也需要系统时间保持这些数据结构不断更新。这些开销一般不是很大,但是当采用不支持异常的方法编译的程序一般比支持异常的程序运行速度更快所占空间也更小。

在理论上,你不能对此进行选择:C++编译器必须支持异常,也就是说,当你不用异常处理时你不能让编译器生产商消除这方面的开销,因为程序一般由多个独立生成的目标文件(object files)组成,只有一个目标文件不进行异常处理并不能代表其他目标文件不进行异常处理。而且即使组成可执行文件的目标文件都不进行异常处理,那么还有它们所连接的程序库呢?如果程序的任何部分使用了异常,其它部分必须也支持异常。否则在运行时程序就不可能提供正确的异常处理。

不过这只是理论,实际上大部分支持异常的编译器生产商都允许你自由控制是否在生成的代码里包含进支持异常的内容。如果你知道你程序的任何部分都不使用try,throw或catch,并且你也知道所连接的程序库也没有使用try,throw或catch,你就可以采用不支持异常处理的方法进行编译,这可以缩小程序的尺寸和提高速度,否则你就得为一个不需要的特性而付出代价。随着时间的推移,使用异处理的程序库开始变得普遍了,上面这种方法将逐渐不能使用,但是根据目前的软件开发情况来看,如果你已经决定不使用任何的异常特性,那么采用不支持异常的方法编译程序是一个性能优化的合理方法。同样这对于想避开异常的程序库来说也是一个性能优化的好方法,这能保证异常不会从客户端程序传递进程序库里,不过同时这样做也会妨碍客户端程序重定义程序库中声明的虚拟函数,并不允许有在客户端定义的回调函数。

使用异常处理的第二个开销来自于try块,无论何时使用它,也就是无论何时你想能够捕获异常,那你都得为此付出代价。不同的编译器实现try块的方法不同,所以编译器与编译器间的开销也不一样。粗略地估计,如果你使用try块,代码的尺寸将增加5%-10%并且运行速度也同比例减慢。这还是假设程序没有抛出异常,我这里讨论的只是在程序里使用try块的开销。为了减少开销,你应该避免使用无用的try块。

编译器为异常规格生成的代码与它们为try块生成的代码一样多,所以一个异常规格一般花掉与tyr块一样多的系统开销。什么?你说你认为异常规格只是一个规格而已,你认为它们不会产生代码?那么好,现在你应该对此有新的认识了。

现在我们来到了问题的核心部分,看看抛出异常的开销。事实上我们不用太关心这个问题,因为异常是很少见的,这种事件的发生往往被描述为exceptional(异常的,罕见的)。80-20规则(参见条款16)告诉我们这样的事件不会对整个程序的性能造成太大的影响。但是我知道你仍旧好奇地想知道如果抛出一个异常到底会有多大的开销,答案是这可能会比较大。与一个正常的函数返回相比,通过抛出异常从函数里返回可能会慢三个数量级。这个开销很大。但是仅仅当你抛出异常时才会有这个开销,一般不会发生。但是如果你用异常表示一个比较普遍的状况,例如完成对数据结构的遍历或结束一个循环,那你必须重新予以考虑。

不过请等一下,你问我是怎么知道这些事情的呢?如果说支持异常对于大多数编译器来说是一个较新的特性,如果说不同的编译器异常方法也不同,那么我如何能说程序的尺寸将增大5%-10%,它的速度也同比例减慢,而且如果有大量的异常被抛出,程序运行速度会呈数量级的减慢呢?答案是令人惊恐的:一些传闻和一些基准测试(benchmarks)(参见条款23)。事实是大部分人包括编译器生产商在异常处理方面几乎没有什么经验,所以尽管我们知道异常确实会带来开销,却很难预测出开销的准确数量。

谨慎的方法是对本条款所叙述的开销有了解,但是不深究具体的数量。(即定性不定量 译者注)不论异常处理的开销有多大我们都得坚持只有必须付出时才付出的原则。为了使你的异常开销最小化,只要可能尽量就采用不支持异常的方法编译程序,把使用try块和异常规格限制在你确实需要它们的地方,并且只有在确为异常的情况下(exceptional)才抛出异常。如果你在性能上仍旧有问题,总体评估一下你的软件以决定异常支持是否是一个起作用的因素。如果是,那就考虑选择其它的编译器,能在C++异常处理方面具有更高实现效率的编译器。

时间: 2024-09-19 12:20:37

了解C++异常处理的系统开支的相关文章

PL/SQL异常处理

     在设计PL/SQL程序时,经常会发生这样或那样的错误,异常处理就是针对错误进行处理的程序段,Oracle 9i中的异常处理分为系统预定义异常处理和自定义异常处理两部分. 系统预定义异常处理     系统预定义异常处理是针对PL/SQL程序编译.执行过程中发生的问题进行处理的程序. 下列代码为正确代码,在[SQLPlus Worksheet]中能够顺利执行.    ―――――――――――――――――――――――――――――――――――――    set serveroutput on  

【SpringMVC整合MyBatis】springmvc异常处理-全局异常处理器开发

异常处理 1.异常处理思路 系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发.测试通过手段减少运行时异常的发生.系统的dao.service.controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图: springmvc提供全局异常处理器(一个系统只有一个异常处理器)进行统一异常处理. 2.自定义异常类 对不同的异常类型定义异常类

联通2010年3G网络开支230亿元

4月12日下午消息,联通在今天发布的年报中表示,2010年资本开支预算为735亿元,其中3G支出为230亿元. 相比较而言,联通2009年资本开支为1124.7亿元,其中3G支出为364亿,占比为32.4%. 2010年的支出预算中,用于扩大3G网络覆盖资本为230亿元,宽带及数据业务支出为153亿元,基础设施及传输网资本开支174亿元,IT系统开支为43亿,以上项目和去年相比,均有下跌. GSM业务开支为80亿元,和去年一样.唯一有所增长的是创新及增值业务平台,今年预算支出为27亿元,而去年为

操作系统课堂笔记(3)SPOOLing系统工作原理与系统调用

SPOOLing系统工作原理 含义: 同时的外围设备联机操作(假脱机技术) 包括: –输入程序模块(预输入进程) –作业调度程序(作业调度进程) –作业控制程序(作业控制进程) –输出程序模块(缓输出进程) •作业执行前用慢速设备将作业预先输入到后援存储器(如磁盘.磁鼓,称为输入井)中,称为预输入 •作业运行中,当要使用数据时,直接从输入井中取出 •作业运行中,需要输出数据时,不必直接启动外部设备输出数据,只需将这些数据写入输出井中 •作业全部运行完毕,再从外部设备输出全部数据和信息,称为缓输出

IDC:2016年第四季度全球融合系统收入同比减少1.4%

根据IDC全球融合系统季度追踪报告,2016年第四季度全球融合系统市场收入同比减少1.4%至30.9亿美元.该季度融合系统市场消耗了1.6EB的新存储容量,相比去年同期小幅增加4%.从2016年全年来看,全球融合系统市场收入增长5.8%至113亿美元. IDC企业存储与融合系统研究总监Eric Sheppard表示:"融合系统市场正在经历变化,我们看到采用新架构.更高自动化.重度使用软件定义技术的产品呈现强劲增长势头,这一增长部分抵消了传统融合系统开支的减少,一些厂商有意识地决定终止他们的部分产

主流七款web服务器软件点评

web|web服务|web服务器|主流 如今互联网的WEB平台种类繁多,各种软硬件组合的WEB系统更是数不胜数,下面就来介绍一下几种常用的WEB服务器: 1.Microsoft IIS Microsoft的Web服务器产品为Internet Information Server (IIS), IIS 是允许在公共Intranet或Internet上发布信息的Web服务器.IIS是目前最流行的Web服务器产品之一,很多著名的网站都是建立在IIS的平台上.IIS提供了一个图形界面的管理工具,称为 I

Win 2000的五则超酷技巧(1)

技巧 相对于Windows 98系统Windows 2000在系统的稳定性方面大大加强了,相对于Windows XP操作系统Windows 2000在硬件方面的要求没有那么高,但是这款操作系统也有不足之处,本文中我们给大家介绍了Windows 2000的五个应用技巧,对你使用Windows 2000系统有不小的帮助. 1.让Windows 2000也使用"Msconfig" 使用NT内核的Windows 2000没有提供Windows 98/XP中的"系统配置实用程序(Msc

选购Web服务器

web|web服务|web服务器 (作者:曹文龙.李维) 通常,建立一个网站要考虑硬件平台.操作系统.数据库.Web服务器.Web应用软件等的选择问题.另外,大多数Web服务器主要是为一种操作系统进行优化的,有的只能运行在一种操作系统上,所以选择Web服务器时,还需要同操作系统联系起来考虑.对于Web服务器的性能,一般要考虑以下几个方面. 响应能力:即Web服务器对多用户浏览信息的响应速度,响应速度越快,单位时间内就可以支持越多的访问量,用户点击的响应速度就越快.前面提到的多线程.多进程.负载均

SQL优化思考

优化     初入oracle殿堂的人,在学写SQL语句时一般会得到一个教诲,那就是exists比in更要高效,但仔细想象要是真的这么简单那干脆去掉in,岂不是省去很多麻烦? 自己对这两种查询语句写法的认识也比较浅显,但是觉得还是比较有效,所以有兴趣的可以瞄一眼哦 ...... 先说IN 他相当对inner table执行一个个带有distinct的子查询语句,然后得到的查询结果集再与outer table进行连接,当然连接的方式和索引的使用仍然同于普通的两表连接. select * from