淺析.net core 拋異常對(duì)性能影響
異常和正常代碼性能旗鼓相當(dāng),但是全局過濾器對(duì)性能影響比較大,大概降低了60%左右,全局過濾器走了管道,但是這跟微軟官方的性能優(yōu)化又有沖突,想必微軟官方也是出于對(duì)全局過濾器異常處理的考慮吧。同時(shí)對(duì)于添加了業(yè)務(wù)的情況下,這個(gè)降低會(huì)被稀釋,沒去做壓測(cè)對(duì)比哈,正常用戶體量還不至于被這個(gè)給影響到穩(wěn)定性。所以怎么取舍看自己
一、前言
在.net 相關(guān)技術(shù)群、網(wǎng)絡(luò)上及身邊技術(shù)討論中看到過關(guān)于大量拋異常會(huì)影響性能這樣的結(jié)論,心中一直就存在各種疑問。項(xiàng)目中使用自定義異常來處理業(yè)務(wù)很爽,但是又擔(dān)心大量拋業(yè)務(wù)異常存在性能問題。
查閱了各種文檔,微軟官方對(duì)性能優(yōu)化這一塊也不建議使用過多的異常,故我心中冒出疑問。
- 疑問一:項(xiàng)目中大量拋出業(yè)務(wù)異常對(duì)性能是否會(huì)受到影響?
二、求證
2.1 使用.net 6 建立了一個(gè)簡(jiǎn)單的web api 項(xiàng)目 新增兩個(gè)壓測(cè)接口api接口代碼如下
/// <summary> /// 正常返回?cái)?shù)據(jù)接口1 /// </summary> /// <returns></returns [HttpGet("Test1")] public async Task<IActionResult> Test() { return Content("1"); } /// <summary> /// 拋異常返回接口2 ,同時(shí)存在全局過濾器 /// </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"); } } //全局過濾器注入 services.AddControllers() .AddMvcOptions(option => { option.Filters.Add<ExceptionFilter>(); });
現(xiàn)在對(duì)test1 接口并發(fā)200的情況下進(jìn)行壓測(cè),持續(xù)15分鐘的壓測(cè)結(jié)果如下:
對(duì)通過全局過濾器捕獲異常并大量拋出異常 在相同壓測(cè)條件情況下的壓測(cè)結(jié)果如下:
對(duì)test1 和test2 同等條件下壓測(cè)結(jié)果對(duì)比
接口 | tps | cpu | 壓測(cè)條件 |
---|---|---|---|
test1 | 10300左右 | cpu消耗90%左右 | 并發(fā)200,持續(xù)壓測(cè) |
test2 | 4300左右 | cpu消耗100%左右 | 并發(fā)200,持續(xù)壓測(cè) |
目前得到的結(jié)論是拋異常確實(shí)影響性能,并且對(duì)性能下降了60% 左右,上面主要是異常流程走了全局過濾器方式,故參考意義不大,下面再進(jìn)一步修改代碼進(jìn)行壓測(cè)
對(duì)test2 代碼進(jìn)行修改如下
/// <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"); } }
再對(duì)修改后的test2 接口進(jìn)行壓測(cè),壓測(cè)結(jié)果如下:
接口 | tps | cpu占用 | 壓測(cè)條件 |
---|---|---|---|
test1 | 10300左右 | 90% 左右 | 并發(fā)200,持續(xù)壓測(cè) |
test2 | 9200左右 | 91% 左右 | 并發(fā)200,持續(xù)壓測(cè) |
進(jìn)一步得到的結(jié)論是try catch 后性能有所提高,跟正常相比還有點(diǎn)點(diǎn)差距,全局過濾器對(duì)性能影響比較大,相當(dāng)于走了管道,但是觀察代碼test1 和test2代碼還存在差距,懷疑test2 代碼中new 了新異常導(dǎo)致性能差異,故再進(jìn)一步進(jìn)行代碼修改求證
對(duì)test1 代碼進(jìn)行修改,修改后的代碼如下:
/// <summary> /// 正常返回?cái)?shù)據(jù)接口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"); }
對(duì)修改后的test1 代碼進(jìn)行壓測(cè)結(jié)果如下:
忘記截圖,大概和修改后的test2 代碼壓測(cè)結(jié)果相差不大,大概tps 9300左右,故還是拿的上一個(gè)圖貼出來,諒解
接口 | tps | cpu占用 | 壓測(cè)條件 |
---|---|---|---|
test1 | 9300左右 | 90%左右 | 并發(fā)200,持續(xù)壓測(cè) |
test2 | 9200左右 | 90%左右 | 并發(fā)200,持續(xù)壓測(cè) |
進(jìn)一步得到的結(jié)論是try catch 后性能和正常返回代碼性能相當(dāng),相差無幾,可以忽略不計(jì)
2.2 最終結(jié)論
- 異常和正常代碼性能旗鼓相當(dāng),但是全局過濾器對(duì)性能影響比較大,大概降低了60%左右,全局過濾器走了管道,但是這跟微軟官方的性能優(yōu)化又有沖突,想必微軟官方也是出于對(duì)全局過濾器異常處理的考慮吧。同時(shí)對(duì)于添加了業(yè)務(wù)的情況下,這個(gè)降低會(huì)被稀釋,沒去做壓測(cè)對(duì)比哈,正常用戶體量還不至于被這個(gè)給影響到穩(wěn)定性。所以怎么取舍看自己
- 這里不否定使用 全局過濾器進(jìn)行業(yè)務(wù)自定義異常捕獲,是否最外層try catch 掉還是全局過濾器去捕獲處理,自己根據(jù)復(fù)雜度和性能兩者中自行取舍,至少全局過濾器處理異常從性能角度上來說不是優(yōu)雅的解決方式
- 對(duì)于非自定義異常,盡量按照微軟官方建議
- 使用 “測(cè)試者-執(zhí)行者”模式
- “嘗試-分析”模式
最后拋出一個(gè)待求證的問題
- 疑問一:大量拋出非自定義異常,性能和正常返回性能對(duì)比會(huì)如何?比如字符串轉(zhuǎn)換int 不使用TryParse 去轉(zhuǎn)換
以上結(jié)論個(gè)人壓測(cè)結(jié)果,如有不對(duì),歡迎交流糾正?
參考文獻(xiàn)
https://docs.microsoft.com/zh-cn/dotnet/standard/design-guidelines/exceptions-and-performance
到此這篇關(guān)于.net core 拋異常對(duì)性能影響的求證之路的文章就介紹到這了,更多相關(guān).net core 拋異常性能影響內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
asp.net Repeater取得CheckBox選中的某行某個(gè)值
Repeater取得CheckBox選中的某行某個(gè)值的實(shí)現(xiàn)代碼2008-07-07Visual?Studio?2022常見的報(bào)錯(cuò)以及處理方案圖文詳解
許多用戶在使用Visual Studio的過程中常會(huì)遇到各種問題,下面這篇文章主要給大家介紹了關(guān)于Visual?Studio?2022常見的報(bào)錯(cuò)以及處理方案的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-04-04.NET 日志系統(tǒng)設(shè)計(jì)思路及實(shí)現(xiàn)代碼
這篇文章主要介紹了.NET 日志系統(tǒng)設(shè)計(jì)思路及實(shí)現(xiàn)代碼,有需要的朋友可以參考一下2013-12-12DataGridView使用BindingNavigator實(shí)現(xiàn)簡(jiǎn)單分頁功能
這篇文章主要介紹了DataGridView使用BindingNavigator實(shí)現(xiàn)簡(jiǎn)單分頁功能,本文主要是通過借用BindingNavigator空殼,文中通過實(shí)例代碼講解的非常詳細(xì),需要的朋友可以參考下2019-11-11建立自定義的數(shù)據(jù)驅(qū)動(dòng)的本地化資源provider
本文探討了自定義的本地化資源提供者.如果想用一個(gè)可替代系統(tǒng)的資源處理方案,例如把所有的資源放入數(shù)據(jù)庫中,而不是放在分散的資源文件里,你可以自定義一個(gè)resource provider.2010-06-06ASP.NET實(shí)現(xiàn)讀取Excel內(nèi)容并在Web上顯示
這篇文章主要介紹了ASP.NET實(shí)現(xiàn)讀取Excel內(nèi)容并在Web上顯示,很實(shí)用的一個(gè)技巧,需要的朋友可以參考下2014-08-08ASP.NET AJAX 4.0的模版編程(Template Programming)介紹
不過當(dāng)我評(píng)估ASP.NET AJAX 4.0的時(shí)候,我確實(shí)被它的特征給震住了。新的特征完全專注于瀏覽器技術(shù),比如XHTML和javascript。 我非常欽佩ASP.NET AJAX小組。2009-07-07Asp.Net Core中基于Session的身份驗(yàn)證的實(shí)現(xiàn)
這篇文章主要介紹了Asp.Net Core中基于Session的身份驗(yàn)證的實(shí)現(xiàn)2018-09-09vs.net控件updatePanel實(shí)現(xiàn)無刷新的方法
vs.net控件updatePanel實(shí)現(xiàn)無刷新的方法,需要的朋友可以參考一下2013-04-04