.net core 抛异常对性能影响的求证之路
一、前言
在.net 社区中曾经听到过很多关于大量抛异常会影响性能这样的结论,心中一直就存在各种疑问。项目中使用自定义异常来处理业务很爽,但是又担心大量抛业务异常存在性能问题。
查阅了各种文档,微软官方对性能优化这一块也不建议使用过多的异常,故我心中冒出疑问。
- 疑问一:项目中大量抛出业务异常对性能是否会受到影响?
二、求证
2.1 使用.net 6 建立了一个简单的web api 项目 新增两个压测接口
- api接口代码如下
/// <summary>
/// 正常返回数据接口1
/// </summary>
/// <returns></returns
[HttpGet("Test1")]
public async Task<IActionResult> Test()
{
return Content("1");
}
/// <summary>
/// 抛异常返回接口2 ,同时存在全局过滤器
/// </summary>
/// <returns></returns
[HttpGet("Test2")]
public async Task<IActionResult> Test2(string open)
{
throw new BusinessException(Model.EnumApiCode.SignWrong);
}
- 全局过滤器代码如下
/// <summary>
/// 全局异常日志
/// </summary>
public class ExceptionFilter : IExceptionFilter
{
/// <summary>
///
/// </summary>
/// <param name="context"></param>
public void OnException(ExceptionContext context)
{
//不做任何处理,直接返回1
context.Result = new JsonResult("1");
}
}
这里注入过滤器代码就不贴上来
现在对test1 接口并发200的情况下进行压测,持续15分钟的压测结果如下:

对通过全局过滤器捕获异常并大量抛出异常 在相同压测条件情况下的压测结果如下:

- 对test1 和test2 同等条件下压测结果对比
| 接口 | tps | cpu | 压测条件 |
|---|---|---|---|
| test1 | 10300左右 | cpu消耗90%左右 | 并发200,持续压测 |
| test1 | 4300左右 | cpu消耗100%左右 | 并发200,持续压测 |
目前得到的结论是抛异常确实影响性能,并且对性能下降了60% 左右,上面主要是异常流程走了全局过滤器方式,故参考意义不大,下面再进一步修改代码进行压测
- 对test2 代码进行修改如下
/// <summary>
/// 抛异常返回接口2 ,直接try catch 不走全局过滤器
/// </summary>
/// <returns></returns
[HttpGet("Test2")]
public async Task<IActionResult> Test2()
{
try
{
throw new BusinessException(Model.EnumApiCode.SignWrong);
}
catch (Exception ex)
{
return Content("1");
}
}
- 再对修改后的test2 接口进行压测,压测结果如下:

| 接口 | tps | cpu占用 | 压测条件 |
|---|---|---|---|
| test1 | 10300左右 | 90% 左右 | 并发200,持续压测 |
| test1 | 9200左右 | 91% 左右 | 并发200,持续压测 |
进一步得到的结论是try catch 后性能有所提高,跟正常相比还有点点差距,全局过滤器对性能影响比较大,相当于走了管道,但是观察代码test1 和test2代码还存在差距,怀疑test2 代码中new 了新异常导致性能差异,故再进一步进行代码修改求证
- 对test1 代码进行修改,修改后的代码如下:
/// <summary>
/// 正常返回数据接口1,但是先new 异常出来,保持跟上面test2 代码一致
/// </summary>
/// <returns></returns
[HttpGet("Test2")]
public async Task<IActionResult> Test2(string open)
{
var ex= new BusinessException(Model.EnumApiCode.SignWrong);
return Content("1");
}
- 对修改后的test1 代码进行压测结果如下:

忘记截图,大概和修改后的test2 代码压测结果相差不大,大概tps 9300左右,故还是拿的上一个图贴出来,谅解
| 接口 | tps | cpu占用 | 压测条件 |
|---|---|---|---|
| test1 | 9300左右 | 90%左右 | 并发200,持续压测 |
| test2 | 9200左右 | 90%左右 | 并发200,持续压测 |
进一步得到的结论是try catch 后性能和正常返回代码性能相当,相差无几,可以忽略不计
2.2 最终结论
- 异常和正常代码性能旗鼓相当,但是全局过滤器对性能影响比较大,大概降低了60%左右,全局过滤器走了管道,但是这跟微软官方的性能优化又有冲突,想必微软官方也是出于对全局过滤器异常处理的考虑吧。
- 不使用全局过滤器进行业务自定义异常捕获,最外层try catch 掉
- 对于非自定义异常,尽量按照微软官方建议
- 使用 “测试者-执行者”模式
- “尝试-分析”模式
最后抛出一个待求证的问题
- 疑问一:大量抛出非自定义异常,性能和正常返回性能对比会如何?比如字符串转换int 不使用TryParse 去转换
以上结论个人压测结果,如有不对,欢迎交流纠正
- 参考文献
- https://docs.microsoft.com/zh-cn/dotnet/standard/design-guidelines/exceptions-and-performance
- https://docs.microsoft.com/zh-cn/aspnet/core/performance/performance-best-practices?view=aspnetcore-6.0#understand-hot-code-paths
.net core 抛异常对性能影响的求证之路的更多相关文章
- C#异常性能影响
何谓异常 很多人在讨论异常的时候很模糊,仿佛所谓异常就是try{}catch{},异常就是Exception,非常的片面,所以导致异常影响性能,XXXX……等很多奇怪的言论,所以在此我意在对异常正名. ...
- .Net Discovery系列之十二-深入理解平台机制与性能影响(下)
上一篇文章中Aicken为大家介绍了.Net平台的垃圾回收机制.即时编译机制与其对性能的影响,这一篇中将继续为大家介绍.Net平台的异常捕获机制与字符串驻留机制. 三.关于异常捕获机制 虽然我们已经很 ...
- Java异常的性能分析
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt276 在Java中抛异常的性能是非常差的.通常来说,抛一个异常大概会消耗10 ...
- JAVA 异常对于性能的影响
陶炳哲 - MAY 12, 2015 在对OneAPM的客户做技术支持时,我们常常会看到很多客户根本没意识到的异常.在消除了这些异常之后,代码运行速度与以前相比大幅提升.这让我们产生一种猜测,就是在代 ...
- .net core 返回业务错误(不抛异常)
在开始之前你需要知道: 1.通过抛异常--全局捕获异常的方式返回业务错误信息性能是非常差的(不知道为什么的可以百度一下) 2.如何将错误信息绑定到mvc模型验证中 自定义返回内容 //返回内容接口 p ...
- Android异常与性能优化相关面试问题-内存管理面试问题详解
内存管理机制概述: 分配机制:操作系统会为每一个进程分配一个合理的内存大小,从而保证每一个进程能够正常的运行,不至于内存不够使用,或者某个进程占用过多的内存. 回收机制:在系统内存不足的时候,系统有一 ...
- netload 加载程序集抛异常----无法加载程序集解决办法
netload 加载程序集抛异常----无法加载程序集 错误信息如下: 无法加载程序集.错误详细信息: System.BadImageFormatException: 未能加载文件或程序集“file: ...
- 盘点 Oracle 11g 中新特性带来的10大性能影响
Oracle的任何一个新版本,总是会带来大量引人瞩目的新特性,但是往往在这些新特性引入之初,首先引起的是一些麻烦,因为对于新技术的不了解.因为对于旧环境的不适应,从Oracle产品到技术服务运维,总是 ...
- ABP在领域事件中异步调用方法抛异常
在领域事件中调用UserRegistrationManager.RegisterAsync抛异常 Call UserRegistrationManager.RegisterAsync() throw ...
随机推荐
- 解决“WARNINGThe remote SSH server rejected X11 forwarding request.“警告
使用xshell连接服务器时,出现了"WARNING! The remote SSH server rejected X11 forwarding request.",意思是&qu ...
- centos7.3 安装oracle 详细过程
centos7.3安装oracle详细过程1.下载Oracle安装包:linux.x64_11gR2_database_1of2.zip 和 linux.x64_11gR2_database_2of2 ...
- hashlib加密模块、logging日志模块
hashlib模块 加密:将明文数据通过一系列算法变成密文数据 目的: 就是为了数据的安全 基本使用 基本使用 import hashlib # 1.先确定算法类型(md5普遍使用) md5 = ha ...
- uTools .SRT 转 .VTT 格式转换自动化小工具
不想用网上的转换工具,要有网,先上传,再下载,可能还要看广告.有些工具也不是很方便.打算配合uTools的自动化助手插件搞一个一键格式转换.
- el-menu菜单 -- unique-opened 子菜单唯一性失效
总结: 点击的是 el-sub-menu . 所以 el-sub-menu 的唯一性是必须的.否则 unique-opened 属性不生效
- 手把手教会 VS2022 设计 Winform 高DPI兼容程序 (net461 net6.0 双出)
本文主要解决两个问题 C# Winform高DPI字体模糊. 高DPI下(缩放>100%), UI设计器一直提示缩放到100%, 如果不重启到100%,设计的控件会乱飞. 建立测试程序 新建.N ...
- 【Hadoop】HBase组件配置
目录 HBase实验步骤: 1.配置时间同步(所有节点) 2.部署HBase(master节点) 3.配置HBase(master节点) 4.拷贝文件到slave节点 5.修改权限,切换用户(所有节点 ...
- Java 8的18个常用日期处理
Java 8的18个常用日期处理 一.简介 伴随 lambda表达式.streams 以及一系列小优化,Java 8 推出了全新的日期时间API. Java处理日期.日历和时间的不足之处:将 java ...
- 2022最新IntellJ IDEA的zheng开发部署文档
目录 前景提示 一.环境整合 构建工具(参考工具部署方式) 二.git 导入编译器 三.模块描述浅析 四.配置文档 1.总配置 2.数据库配置 3.密码设置 4.配置建议 五.在IDEA中执行MySQ ...
- vue下一代状态管理Pinia.js 保证你看的明明白白!
1.pinia的简单介绍 Pinia最初是在2019年11月左右重新设计使用Composition API的 Vue 商店外观的实验. 从那时起,最初的原则相同,但 Pinia 适用于 Vue 2 和 ...