尝试捕获性能c#

try catch for performance c#

我对Try-Catch的了解有限。但我想知道它是否可以用来获得性能。

例如,我创建的这个体素引擎的函数如下:

1
2
3
4
5
6
Block GetBlockInChunk(Vector Position){
    if(InBound(Position)){
        return Database.GetBlock();
    }
    return null;
}

这里必须检查给定位置的边界,使用try catch,然后可以删除它们?

1
2
3
4
5
6
7
8
Block GetBlockInChunk(Vector Position){
    try{
        return Database.GetBlock();
    }
    catch{
        return null;
    }
}

我觉得这可能是很糟糕的练习,但我很好奇。


我在上面的注释中提供的链接显示了一个描述,当if语句阻止抛出异常时,为什么不应该使用try-catch,但是为了以实际数字显示性能,我编写了这个快速的小测试程序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Stopwatch watch = new Stopwatch();

int[] testArray = new int[] { 1, 2, 3, 4, 5 };
int? test = null;

watch.Start();
for (int i = 0; i < 10000; i++)
{
    try
    {
        testArray[(int)test] = 0;
    }
    catch { }
}
watch.Stop();

Console.WriteLine("try-catch result:");
Console.WriteLine(watch.Elapsed);
Console.WriteLine();

watch.Restart();
for (int i = 0; i < 10000; i++)
{
    if (test != null)
        testArray[(int)test] = 0;
}
watch.Stop();

Console.WriteLine("if-statement result:");
Console.WriteLine(watch.Elapsed);

程序的结果是:

1
2
3
4
5
try-catch result:
00:00:32.6764911

if-statement result:
00:00:00.0001047

正如您所看到的,当捕获异常时,Try-Catch方法会带来很大的开销,在我的机器上完成10000个周期需要30秒以上。另一方面,if语句的运行速度非常快,基本上是即时的。与尝试捕获相比,这是在3000000%附近的性能改进。

(这不是一个严格的基准,有很多方法可以编写它并以不同的方式运行它以获得更精确的数字,但这可以让您更好地了解在尽可能多的情况下使用if语句而不是try-catch的效率。)


大约两年后,但它仍然是相关的…

我尊重其他的回答,但我相信这里有一个基本的误解是为了试着抓住。Try-Catch是C和Dotnet中一种非常有效的方法,用于识别代码开发和生命周期中的错误。它从来不是一个用来使用不同的工具,如果它被激发了,这意味着你有一个需要修复的bug。

它要解决的问题是,标准的错误消息会停止代码,然后您需要深入研究。通过尝试和捕获,您可以知道问题发生在哪种方法中,并缩小搜索范围。

作为标准配置,我用try catch包装了所有方法,并添加了一个附加功能,该功能使用方法的名称和附加的基本信息(如时间)将错误消息写入调试文件,甚至在代码处于生产状态时也可以访问这些文件。这是无价之宝!

就性能而言,如果尝试捕获未触发(这应该是正常的),则不会降低性能,因为它只是一个简单的翘曲机。如果有人真的对高性能非常感兴趣,并且每一个分数都很重要,那么可以使用预编译条件(if…)来消除它。

希望这是有帮助的。