C#异常过滤器性能

C#异常过滤器性能,c#,performance,visual-studio-2015,C#,Performance,Visual Studio 2015,当抛出异常时,VS2015中引入的C#异常过滤器是否会对性能、内存使用或堆栈产生任何影响 异常筛选器: try { … } catch (Exception e) when (e.Message == "Hello world") { // do stuff } 诗句传统的接球和重投: try { … } catch (Exception e) { if (e.Message == "Hello world") { // do stuff }

当抛出异常时,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;
    }
}
新的C#6.0异常过滤功能基本上颠覆了捕获异常然后检查条件的逻辑

区别在于:

  • 在第一个示例中,首先检查条件,然后可能捕获异常
  • 在第二个示例中,您每次都捕获异常,然后根据内部条件决定要执行的操作
因此,我不确定具体的性能影响是什么,但我认为总体而言,您的情况会更好

如果不满足该条件,则不必展开堆栈,也不必承担捕获和重试的成本(异常未捕获/重试..它根本未捕获),或者执行
catch
语句中可能包含的任何其他逻辑。

Summary BenchmarkDotNet=v0.11.5,OS=Windows。。 英特尔酷睿i7、.NET酷睿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 |
+-----------------+--------+----------------------+-----------------+----------------+-----------------+------+------------+-------+-------+------------+
传说
  • N:“N”参数的值
  • SearchedQuerysMatch:“SearchedQuerysMatch”参数的值
  • 平均值:所有测量值的算术平均值
  • 错误:99.9%置信区间的一半
  • STDEV:所有测量值的标准偏差
  • 等级:当前基准平均值在所有基准中的相对位置(阿拉伯语)
  • 第0代:GC第0代每1000次操作收集一次
  • 第1代:GC第1代每1000次操作收集
  • 第2代:GC第2代每1000次操作收集
  • 已分配:每个操作分配的内存(仅受管理,包括1KB=1024B)
  • 1美国:1微秒(0.000001秒)
示例代码
公共类程序
{
[CoreJob]
[RPlotExporter、RankColumn、MemoryDiagnoser]
公共类集合包含
{
private const string SearchedMessage=“hello world”;
[参数(1,1,000,100,000)]
私人int N;
[参数(真、假)]
私有布尔搜索查询匹配;
[基准]
public void ExceptionFilter()=>ExecuteTestFor(异常=>
{
尝试
{
抛出异常;
}
捕获(异常ex)时(ex.Message==SearchedMessage)
{
}
});
[基准]
public void IfStatement()=>ExecuteTestFor(异常=>
{
尝试
{
抛出异常;
}
捕获(例外情况除外)
{
if(例如,Message==SearchedMessage)
{
返回;
}
投掷;
}
});
私有void ExecuteTestFor(操作testedExceptionHandling)
{
对于(int i=0;iBenchmarkRunner.Run();
}

你不应该每秒抛出10000个异常,所以这真的不重要。嘿,Soner Gonul,我在这里问一下,互联网合作找到了答案,然后从现在到年底,每个人都可以通过自己选择的搜索引擎找到答案?@JamesNewton King你在这方面有什么新发现吗?我也很感兴趣,到目前为止,这里发布的所有答案都是推测性的,只描述了该功能在逻辑上是如何工作的,而不是它是如何实现的。你有这方面的来源吗?许多新的好东西只是帮助人们编写更干净的代码的语法糖,所以我认为这实际上可以编译为捕获异常,检查并在需要时再次抛出它。我还没有真正研究过它,所以任何更可靠的信息都是很好的!