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;
}
}
答案 0 :(得分:2)
异常过滤的新C#6.0特性基本上颠覆了捕获异常然后检查条件的逻辑。
区别在于:
所以我不确定具体的性能影响是什么,但我认为你的整体情况会更好。
如果条件没有达到,那么你不必展开堆栈,或者招致捕获和重新抛出的成本(异常没有被捕获/重新抛出......它根本就没有被捕获),或执行任何您可能已包含在catch
语句中的其他逻辑。
答案 1 :(得分:2)
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 |
+-----------------+--------+----------------------+-----------------+----------------+-----------------+------+------------+-------+-------+------------+
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>();
}