c#异常过滤器性能
本文关键字:性能 过滤器 异常 | 更新日期: 2023-09-27 18:02:17
在VS2015中引入的c#异常过滤器在抛出异常时对性能,内存使用或堆栈有任何影响吗?
异常过滤器:try { … }
catch (Exception e) when (e.Message == "Hello world")
{
// do stuff
}
对比传统的接球和再抛:
try { … }
catch (Exception e)
{
if (e.Message == "Hello world")
{
// do stuff
}
else
{
throw;
}
}
总结
BenchmarkDotNet=v0.11.5, OS=Windows .
Intel Core i7, .NET Core 2.2.5
+-----------------+--------+----------------------+-----------------+----------------+-----------------+------+------------+-------+-------+------------+
| Method | N | SearchedQueryIsMatch | Mean | Error | StdDev | Rank | Gen 0 | Gen 1 | Gen 2 | Allocated |
+-----------------+--------+----------------------+-----------------+----------------+-----------------+------+------------+-------+-------+------------+
| ExceptionFilter | 1 | False | 21.29 us | 0.3780 us | 0.6912 us | 2 | 0.0916 | - | - | 440 B |
| IfStatement | 1 | False | 40.35 us | 0.7339 us | 0.6505 us | 3 | 0.0610 | - | - | 440 B |
| ExceptionFilter | 1 | True | 19.28 us | 0.3831 us | 0.8409 us | 1 | 0.0305 | - | - | 216 B |
| IfStatement | 1 | True | 19.08 us | 0.4230 us | 0.6331 us | 1 | 0.0305 | - | - | 216 B |
| ExceptionFilter | 1000 | False | 20,813.47 us | 413.2388 us | 537.3272 us | 5 | 93.7500 | - | - | 440000 B |
| IfStatement | 1000 | False | 40,412.30 us | 645.9158 us | 604.1901 us | 6 | 76.9231 | - | - | 440000 B |
| ExceptionFilter | 1000 | True | 18,433.85 us | 257.8815 us | 228.6052 us | 4 | 31.2500 | - | - | 216000 B |
| IfStatement | 1000 | True | 18,510.49 us | 366.2362 us | 324.6588 us | 4 | 31.2500 | - | - | 216000 B |
| ExceptionFilter | 100000 | False | 2,037,740.01 us | 46,797.1438 us | 57,471.0953 us | 8 | 10000.0000 | - | - | 44000000 B |
| IfStatement | 100000 | False | 4,057,642.15 us | 80,944.2280 us | 179,366.8182 us | 9 | 10000.0000 | - | - | 44000000 B |
| ExceptionFilter | 100000 | True | 1,835,382.75 us | 35,810.5411 us | 42,629.9019 us | 7 | 5000.0000 | - | - | 21600000 B |
| IfStatement | 100000 | True | 1,833,703.56 us | 34,189.6215 us | 31,980.9932 us | 7 | 5000.0000 | - | - | 21600000 B |
+-----------------+--------+----------------------+-----------------+----------------+-----------------+------+------------+-------+-------+------------+
<标题>传说h1> li>N: N参数的值 public class Program
{
[CoreJob]
[RPlotExporter, RankColumn, MemoryDiagnoser]
public class CollectionsContains
{
private const string SearchedMessage = "hello world";
[Params(1, 1_000, 100_000)]
private int N;
[Params(true, false)]
private bool SearchedQueryIsMatch;
[Benchmark]
public void ExceptionFilter() => ExecuteTestFor(exception =>
{
try
{
throw exception;
}
catch (Exception ex) when (ex.Message == SearchedMessage)
{
}
});
[Benchmark]
public void IfStatement() => ExecuteTestFor(exception =>
{
try
{
throw exception;
}
catch (Exception ex)
{
if (ex.Message == SearchedMessage)
{
return;
}
throw;
}
});
private void ExecuteTestFor(Action<Exception> testedExceptionHandling)
{
for (int i = 0; i < N; i++)
{
try
{
var exception = new Exception(SearchedQueryIsMatch ? SearchedMessage : Guid.NewGuid().ToString());
testedExceptionHandling(exception);
}
catch
{
}
}
}
}
private static void Main() => BenchmarkRunner.Run<CollectionsContains>();
}
标题>标题>c# 6.0的异常过滤新特性基本上改变了捕获异常然后检查条件的逻辑。
区别是:
- 在第一个示例中,首先检查条件,然后可能捕获异常。
- 在第二个示例中,每次捕获异常,然后根据内部条件决定做什么。
所以我不确定确切的性能影响是什么,但我认为你总体上更好。
如果条件不满足,则不必展开堆栈,或者产生捕获和重新抛出的成本(异常不会被捕获/重新抛出)。它只是根本没有被捕获),或者执行您可能包含在catch
语句中的任何其他逻辑。