关于C#的trycatch造成的性能问题

_

以前在编写业务时,发现trycatch块会造成一小段时间卡顿,如接口无异常情况下22ms,第一次异常则需要2s,第二次异常则25s

所以记录一下相关内容。

码字到现在,从现象上看,可以先预设几个点

1.try块对性能无影响

2.catch会对性能造成较大影响

3.Exception会对try块内容进行收集

额外:

1. IL trycatch代码,会出现与C#类似的trycatch结构,不明显看出可分析点

default void Main ()  cil managed
{
    .entrypoint
    .maxstack 3
    .locals init (
            int32   V_0)
    IL_0000:  ldc.i4.0
    IL_0001:  stloc.0
    .try {
      IL_0002:  ldloc.0
      IL_0003:  ldc.i4.5
      IL_0004:  add
      IL_0005:  stloc.0
      IL_0006:  leave IL_0013
    } 
    catch class [mscorlib]System.Exception {
      IL_000b:  pop
      IL_000c:  rethrow
      IL_000e:  leave IL_0013
    }
    IL_0013:  ret
}

通过在Core测试

在全程不会触发异常时,try在一些场景会比没有try更快。

若一直引发异常,会导致耗时极长。

总结:

翻阅很多资料,似乎现在也有很多人trycatch有着不同的见解。

而大多人都认为try块并不会引起性能问题,而在引发异常时,将会消耗较大的性能。

也有人说异常时间复杂O(1),在之前我确实见过这种情况,但目前也还原不出。

在异常在深层时,对性能的消耗会更大,可能是因其Try块的体积原因。

额外的trycatch是很基础的功能,这并不是要求我们如何去控制这部分的使用,

在Web开发中,大部分使用try的地方并不多,一般就是底层框架、第三方插件、网络通信会需要到try

在其都不会出现大量使用Try的场景(网络通信额外处理),底层和插件一般情况都是因配置、输入参数不符合的情况会触发异常

Web开发可完全使用全局异常捕获并记录异常内容,对于这种框架型的异常是必须解决的,所以能独立一块参数验证时完全可以的,

而无法处理的异常,对于程序来说是致命,更不可能让其运行。

在一般情况下,应该少使trycatch,因为该功能是帮助我们捕获异常,那么就说明这里会出现异常。

更多情况下,应该使用判断去处理一些特殊情况,而不是一味往外抛。

我们可以添加触发器,减catch的出现。

像所学的一样,“底层无法处理的各种异常,再使trycatch往上抛”才是合理的。

分享一个学习设计模式的网站 Refactoring.Guru 2021-08-20
初次接触Docker 2021-08-20