当 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 语句没有显式捕获异常对象时,它们是不是更快/更便宜? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

使用try和catch捕获异常

JAVA中try catch捕获异常的问题

异常的处理

Java异常处理的基础知识

Java中的异常处理try catch(第八周课堂示例总结)

异常处理(动手动脑)