-3

I know that exceptions are not cheap because stack traces have to be gathered, etc. Are there any performance gains to doing this

try
{
    //stuff
}
catch
{
    // other stuff - don’t capture “ex”
}

instead of this?

try
{
    //stuff
}
catch (Exception ex)
{
    // other stuff - capture (and don’t use) “ex”
}

My guess is that the runtime still throws an exception, which entails all of the usual overhead, but I am hoping someone can confirm.

user2864740
  • 60,010
  • 15
  • 145
  • 220
NSouth
  • 5,067
  • 7
  • 48
  • 83
  • 5
    measure measure MEASURE! – Daniel A. White Aug 27 '20 at 20:47
  • 1
    I'm not sure of the relevance of this question... don't catch an Exception if you don't need to handle it. If you need to handle the exception -- handle it according to what you need, right? – devlin carnate Aug 27 '20 at 20:49
  • 2
    To your last sentence, `try ... catch` has no effect on whether an exception is thrown or not, just whether it's _caught_. – Lance U. Matthews Aug 27 '20 at 20:50
  • 1
    Do you have a performance problem? Ideally you shouldn't have *any* exceptions being thrown in performance bottlenecks unless something actually breaks... in which case, you don't care about performance any longer, do you? – J... Aug 27 '20 at 20:52
  • 1
    downvotes are likely due to lack of research effort (i.e. not measuring the performance before coming with a question) – Rufus L Aug 27 '20 at 20:55
  • In both cases checking if there is an exception in try block after each instruction is necessary and it is slower. So it is not good to have large piece of code in try block if you don't need it. That is crucial if you are thinking about how exceptions affect performance, not how many catches you have. – Lazar Đorđević Aug 27 '20 at 20:57
  • 1
    Similar recent question about `catch (Exception ex)` vs. `catch (Exception _)` and (mistakenly attributing as a) variable discard: [Performance advantage of discard operator](https://stackoverflow.com/q/61566181/150605) – Lance U. Matthews Aug 27 '20 at 20:58

2 Answers2

3

Yes, the exception is still generated and "captured." This is because the exception could still be caught at a higher level.

Try this to see what I mean:

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);
}
user2864740
  • 60,010
  • 15
  • 145
  • 220
John Wu
  • 50,556
  • 8
  • 44
  • 80
1

Here you some scaffolding to make your own research. I throw exception 1000 times measuring time. There is no performance improvement with ommiting the exception variable.

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);
  • 1
    Unless exception creation [takes much longer than the time saved](https://stackoverflow.com/a/31476517/327083). Better to create the exception once and throw the same one over and over. This puts the highest burden on the exception *handling* in the loop. – J... Aug 27 '20 at 21:19
  • 1
    @J... You are right of course. I checked and found out that an exception creation is really fast and doesn't change results. But I agree with you. And it is even better to measure actual code performance and not this strange empty catches. :) – Konstantin Borisov Aug 27 '20 at 21:27
  • 1
    Good to know. I wasn't sure if it was important or not, but thanks for checking! – J... Aug 27 '20 at 21:27
  • Not that this is likely to affect the end result, but what is the purpose of `ts.Milliseconds / 10`? Also, `TimeSpan` supports [standard](https://learn.microsoft.com/dotnet/standard/base-types/standard-timespan-format-strings) and [custom](https://learn.microsoft.com/dotnet/standard/base-types/custom-timespan-format-strings) format strings, so you could rewrite that to simply `Console.WriteLine(@"Elapsed: {0:hh\:mm\:ss\.ff}", sw.Elapsed);`. – Lance U. Matthews Aug 27 '20 at 22:04