当 catch 语句没有显式捕获异常对象时,它们是不是更快/更便宜? [关闭]
Posted
技术标签:
【中文标题】当 catch 语句没有显式捕获异常对象时,它们是不是更快/更便宜? [关闭]【英文标题】:Are catch statements faster/cheaper when they don't explicitly capture the exception object? [closed]当 catch 语句没有显式捕获异常对象时,它们是否更快/更便宜? [关闭] 【发布时间】:2020-12-16 19:22:23 【问题描述】:我知道异常并不便宜,因为必须收集堆栈跟踪等。这样做有什么性能提升
try
//stuff
catch
// other stuff - don’t capture “ex”
而不是这个?
try
//stuff
catch (Exception ex)
// other stuff - capture (and don’t use) “ex”
我的猜测是运行时仍然会抛出异常,这需要所有通常的开销,但我希望有人可以确认。
【问题讨论】:
测量测量测量! 我不确定这个问题的相关性......如果您不需要处理它,请不要捕获异常。如果你需要处理异常——根据你的需要处理,对吧? 对于你的最后一句话,try ... catch
对是否抛出异常没有影响,只是它是否捕获。
您有性能问题吗?理想情况下,您不应该在性能瓶颈中引发任何异常,除非确实发生了故障……在这种情况下,您不再关心性能,对吗?
投反对票可能是由于缺乏研究工作(即在提出问题之前未衡量性能)
【参考方案1】:
是的,仍然会生成并“捕获”异常。这是因为异常仍然可以在更高级别被捕获。
试试这个看看我的意思:
try
try
throw new Exception("Foo");
catch
throw; //What is it throwing, if not a captured exception?
catch(System.Exception e)
// e is refers to the original exception object thrown
Console.WriteLine(e.Message);
【讨论】:
【参考方案2】:这里有一些脚手架来进行自己的研究。我抛出异常 1000 次测量时间。省略异常变量并没有提高性能。
const int num = 1000;
Stopwatch sw = new Stopwatch();
sw.Start();
for(var i=0;i<num;i++)
try
throw new Exception();
catch /*(Exception ex)*/
sw.Stop();
TimeSpan ts = sw.Elapsed;
string elapsedTime = String.Format("0:00:1:00:2:00.3:00",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
Console.WriteLine("Elapsed: "+elapsedTime);
【讨论】:
除非创建异常takes much longer than the time saved。最好创建一次异常并一遍又一遍地抛出相同的异常。这给循环中的异常处理带来了最大的负担。 @J... 你当然是对的。我检查并发现异常创建非常快并且不会改变结果。但我同意你的看法。更好的是测量实际代码性能,而不是这个奇怪的空捕获。 :) 很高兴知道。我不确定它是否重要,但感谢您的检查! 不是说这可能会影响最终结果,而是ts.Milliseconds / 10
的目的是什么?此外,TimeSpan
支持standard 和custom 格式字符串,因此您可以将其重写为简单的Console.WriteLine(@"Elapsed: 0:hh\:mm\:ss\.ff", sw.Elapsed);
。以上是关于当 catch 语句没有显式捕获异常对象时,它们是不是更快/更便宜? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章