C# 异常过滤器性能

标签 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
    }
    else
    {
        throw;
    }
}

最佳答案

摘要

BenchmarkDotNet=v0.11.5,操作系统=Windows ..

英特尔酷睿 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 |
+-----------------+--------+----------------------+-----------------+----------------+-----------------+------+------------+-------+-------+------------+

传奇

  • N:“N”参数的值
  • SearchedQueryIsMatch:“SearchedQueryIsMatch”参数的值
  • 平均值:所有测量值的算术平均值
  • 误差:99.9% 置信区间的一半
  • StdDev:所有测量值的标准偏差
  • 排名:当前基准平均值在所有基准中的相对位置(阿拉伯风格)
  • Gen 0:GC Generation 0 每 1000 次操作收集
  • Gen 1:GC 第 1 代每 1000 次操作收集
  • Gen 2:GC 第 2 代每 1000 次操作收集
  • 已分配:每个操作分配的内存(仅限托管,包含在内,1KB = 1024B)
  • 1 微秒:1 微秒(0.000001 秒)

示例代码

    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# 异常过滤器性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31357038/

相关文章:

c# - 我在属性 setter 中进入无限循环

c# - 如何使用 C++ DLL 中的 C# 代码

c# - 好奇的用户在应用程序处于后台进程时按键,如何忽略这种类型的额外按键

mysql - 我如何加速这个 1.7 秒的 Mysql 查询?

c# - 在 Visual Studio 上打开自定义工具窗口,而不从“ View ”菜单调用它

c# - ASP.NET 核心 : Very slow (first) page load time with development environment variable

c# - Windows UWP BluetoothLE设备缓存

asp.net - 创建对象的成本是多少

Android/iPhone 应用程序...使用基于互联网的 API 与本地 API

c++ - 在 QT 中动态创建 GUI,无需在 Visual Studio 中使用表单