0

0

try-catch会影响程序性能吗

巴扎黑

巴扎黑

发布时间:2016-12-20 11:08:56

|

1816人浏览过

|

来源于php中文网

原创

try-catch真的会影响程序性能吗 
今天和tl争论try-catch使用上的问题,是否为了代码看上去的美观而把该方法下得所有代码都放到try-catch中,我理所当然的持反对意见,但对try-catch的实现机制没有深入研究过,不能说出有说服力的理由,今天在网上找到个.net的try-catch分析,和大家分享下 
    很多帖子都分析过try-catch的机制,以及其对性能的影响。 
   但是并没有证据证明,try-catch过于损耗了系统的性能,尤其是在托管环境下。记得园子里有位网友使用stopwatch分析过try-catch在不同情况下,与无try-catch的代码相比,代码运行的时间指标,结果并没有很大差异。 
    下面我来结合il分析一下try-catch吧。 
    ● 机制分析 
    .net 中基本的异常捕获与处理机制是由try…catch…finally块来完成的,它们分别完成了异常的监测、捕获与处理工作。一个try块可以对应零个或多个catch块,可以对应零个或一个finally块。不过没有catch的try似乎没有什么意义,如果try对应了多个catch,那么监测到异常后,clr会自上而下搜索catch块的代码,并通过异常过滤器筛选对应的异常,如果没有找到,那么clr将沿着调用堆栈,向更高层搜索匹配的异常,如果已到堆栈顶部依然没有找到对应的异常,就会抛出未处理的异常了,这时catch块中的代码并不会被执行。所以距离try最近的catch块将最先被遍历到。 
    如有以下代码: 
    try 
   { 
       convert.toint32("try"); 
   } 
       catch (formatexception ex1) 
   { 
       string catchformatexception = "catchformatexception"; 
   } 
       catch (nullreferenceexception ex2) 
   { 
       string catchnullreferenceexception = "catchnullreferenceexception"; 
   } 
   finally 
   { 
       string finally = "finally"; 
   } 
  对应il如下: 
.method private hidebysig instance void form1_load(object sender, 
class [mscorlib]system.eventargs e) cil managed 

// code size 53 (0x35) 
.maxstack 1 
.locals init ([0] class [mscorlib]system.formatexception ex1, 
[1] string catchformatexception, 
[2] class [mscorlib]system.nullreferenceexception ex2, 
[3] string catchnullreferenceexception, 
[4] string finally) 
il_0000: nop 
il_0001: nop 
il_0002: ldstr "try" 
il_0007: call int32 [mscorlib]system.convert::toint32(string) 
il_000c: pop 
il_000d: nop 
il_000e: leave.s il_0026 
il_0010: stloc.0 
il_0011: nop 
il_0012: ldstr "catchformatexception" 
il_0017: stloc.1 
il_0018: nop 
il_0019: leave.s il_0026 
il_001b: stloc.2 
il_001c: nop 
il_001d: ldstr "catchnullreferenceexception" 
il_0022: stloc.3 
il_0023: nop 
il_0024: leave.s il_0026 
il_0026: nop 
il_0027: leave.s il_0033 
il_0029: nop 
il_002a: ldstr "finally" 
il_002f: stloc.s finally 
il_0031: nop 
il_0032: endfinally 
il_0033: nop 
il_0034: ret 
il_0035: 
// exception count 3 
.try il_0001 to il_0010 catch [mscorlib]system.formatexception handler il_0010 to il_001b 
.try il_0001 to il_0010 catch [mscorlib]system.nullreferenceexception handler il_001b to il_0026 
.try il_0001 to il_0029 finally handler il_0029 to il_0033 
} // end of method form1::form1_load 
    末尾的几行代码揭示出il是怎样处理异常处理的。最后三行的每一个item被称作exception handing clause,ehc组成exception handing table,eht与正常代码之间由ret返回指令隔开。 
    可以看出,formatexception排列在eht的第一位。 
    当代码成功执行或反之而返回后,clr会遍历eht: 
    1. 如果抛出异常, clr会根据抛出异常的代码的“地址”找到对应的ehc(il_0001 to il_0010为检测代码的范围),这个例子中clr将找到2条ehc, formatexception会最先被遍历到,且为适合的ehc。 
    2. 如果返回的代码地址在il_0001 to il_0029内,那么还会执行finally handler 即il_0029 to il_0033中的代码,不管是否因成功执行代码而返回。 
    事实上,catch与finally的遍历工作是分开进行的,如上文所言,clr首先做的是遍历catch,当找到合适的catch块后,再遍历与之对应finally;而且这个过程会递归进行至少两次,因为编译器将c#的try…catch…finally翻译成il中的两层嵌套。 
当然如果没有找到对应的catch块,那么clr会直接执行finally,然后立即中断所有线程。finally块中的代码肯定会被执行,无论try是否检测到了异常。 
    ● 改进建议 
    由上面的内容可以得出: 
    如果使用了“try-catch”,且捕获到了异常,clr做的只不过是遍历exception handing table中的catch项;然后再次遍历exception handing table中的finally项,所用时间几乎都花费在遍历exception handing table上;而如果没有捕获到异常,clr只是遍历exception handing table中的finally项,所需时间微乎其微。 
    而“try-catch”遍历后的执行对应操作所用时间,则根据你的具体代码所定,“try-catch”引起的只是监控与触发,不应将这部分的代码时间也算“try-catch”的消耗。 
    所以,可以从性能和代码评审两方面考虑,一般建议有以下几点准则: 
    1.尽量给clr一个明确的异常信息,不要使用exception去过滤异常 
    2.尽量不要将try…catch写在循环中 
    3. try尽量少的代码,如果有必要可以使用多个catch块,并且将最有可能抛出的异常类型,书写在距离try最近的位置 
    4.不要只声明一个exception对象,而不去处理它。这样做白白增加了exception handing table的长度。 
    5.使用性能计数器实用工具的“clr exceptions”检测异常情况,并适当优化 
    6.使用成员的try-parse模式,如果抛出异常,那么用false代替它 
    结论,try-catch虽然会消费一点时间,但程序人员大可不必谈虎色变,通过上面的分析,与其说“try-catch”会损耗或影响性能,不如说“try-catch”与其他代码一样,只是性能的普通消费者,但出于代码书写评审方面的考虑,还是尽量关照一下“try-catch”吧。

eMart 网店系统
eMart 网店系统

功能列表:底层程序与前台页面分离的效果,对页面的修改无需改动任何程序代码。完善的标签系统,支持自定义标签,公用标签,快捷标签,动态标签,静态标签等等,支持标签内的vbs语法,原则上运用这些标签可以制作出任何想要的页面效果。兼容原来的栏目系统,可以很方便的插入一个栏目或者一个栏目组到页面的任何位置。底层模版解析程序具有非常高的效率,稳定性和容错性,即使模版中有错误的标签也不会影响页面的显示。所有的标

下载

相关文章

数码产品性能查询
数码产品性能查询

该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
clawdbot ai使用教程 保姆级clawdbot部署安装手册
clawdbot ai使用教程 保姆级clawdbot部署安装手册

Clawdbot是一个“有灵魂”的AI助手,可以帮用户清空收件箱、发送电子邮件、管理日历、办理航班值机等等,并且可以接入用户常用的任何聊天APP,所有的操作均可通过WhatsApp、Telegram等平台完成,用户只需通过对话,就能操控设备自动执行各类任务。

8

2026.01.29

clawdbot龙虾机器人官网入口 clawdbot ai官方网站地址
clawdbot龙虾机器人官网入口 clawdbot ai官方网站地址

clawdbot龙虾机器人官网入口:https://clawd.bot/,clawdbot ai是一个“有灵魂”的AI助手,可以帮用户清空收件箱、发送电子邮件、管理日历、办理航班值机等等,并且可以接入用户常用的任何聊天APP,所有的操作均可通过WhatsApp、Telegram等平台完成,用户只需通过对话,就能操控设备自动执行各类任务。

1

2026.01.29

Golang 网络安全与加密实战
Golang 网络安全与加密实战

本专题系统讲解 Golang 在网络安全与加密技术中的应用,包括对称加密与非对称加密(AES、RSA)、哈希与数字签名、JWT身份认证、SSL/TLS 安全通信、常见网络攻击防范(如SQL注入、XSS、CSRF)及其防护措施。通过实战案例,帮助学习者掌握 如何使用 Go 语言保障网络通信的安全性,保护用户数据与隐私。

5

2026.01.29

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

517

2026.01.28

包子漫画在线官方入口大全
包子漫画在线官方入口大全

本合集汇总了包子漫画2026最新官方在线观看入口,涵盖备用域名、正版无广告链接及多端适配地址,助你畅享12700+高清漫画资源。阅读专题下面的文章了解更多详细内容。

184

2026.01.28

ao3中文版官网地址大全
ao3中文版官网地址大全

AO3最新中文版官网入口合集,汇总2026年主站及国内优化镜像链接,支持简体中文界面、无广告阅读与多设备同步。阅读专题下面的文章了解更多详细内容。

318

2026.01.28

php怎么写接口教程
php怎么写接口教程

本合集涵盖PHP接口开发基础、RESTful API设计、数据交互与安全处理等实用教程,助你快速掌握PHP接口编写技巧。阅读专题下面的文章了解更多详细内容。

10

2026.01.28

php中文乱码如何解决
php中文乱码如何解决

本文整理了php中文乱码如何解决及解决方法,阅读节专题下面的文章了解更多详细内容。

13

2026.01.28

Java 消息队列与异步架构实战
Java 消息队列与异步架构实战

本专题系统讲解 Java 在消息队列与异步系统架构中的核心应用,涵盖消息队列基本原理、Kafka 与 RabbitMQ 的使用场景对比、生产者与消费者模型、消息可靠性与顺序性保障、重复消费与幂等处理,以及在高并发系统中的异步解耦设计。通过实战案例,帮助学习者掌握 使用 Java 构建高吞吐、高可靠异步消息系统的完整思路。

10

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

相关下载

更多

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3万人学习

C# 教程
C# 教程

共94课时 | 7.9万人学习

Java 教程
Java 教程

共578课时 | 52.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号