1

I've heard that try/catches are considered to be bad for performance, but that if you're rarely expecting to throw exceptions then they are considered a better way to return failure information rather than using methods/functions with Boolean values.

Does using try/catch in this manner better or worse for performance? It certainly makes coding easier.

Example:

void DoSomething(){
  try{
    DoSomethingIffy();
  } catch {
    // Yikes! Do failure stuff
  }
}

void DoSomethingIffy(){
  if (rareCondition) {
    throw new Exception("oops");
  }
}

vs

void DoSomething(){
  if (!DoSomethingIffy()) {
    // Yikes! Do failure stuff
  }
}

bool DoSomethingIffy(){
  if (rareCondition) {
    return false;
  }
  else {
    return true;
  }
}
John Saunders
  • 160,644
  • 26
  • 247
  • 397
Zain Rizvi
  • 23,586
  • 22
  • 91
  • 133
  • 2
    Use exceptions. They are only expensive to `throw`, not to `try`. And you get a stack-trace, and a nice message, etc. Obviously don't throw an exception unless the situation is actually *exceptional* - something you don't expect to happen "if everything goes right". – Blorgbeard Sep 06 '13 at 02:39
  • 1
    The most efficient program in the world is useless if it gives you the wrong result. Exceptions are a tool that - when used judiciously - can improve the correctness and error-handling of your software. Exceptions force you to handle a problem (even if by terminating the process), whereas a return code places the onus on the caller to detect and handle the problem. – Kent Boogaart Sep 06 '13 at 02:41
  • 3
    Don't use empty catches, only catch exceptions if you have a meaningful way of handling them. – sa_ddam213 Sep 06 '13 at 02:41
  • 4
    Don't overly worry about performance until you know something is an issue. For know if something exceptional feel free to use an exception. – dcaswell Sep 06 '13 at 02:41

2 Answers2

1

If you are seeing or expect to see throw rates greater than 100 per second then it will likely have a performance impact. (See .NET Framework Design Guidelines: Exception Throwing) In this case it would be beneficial to use a design that avoids throwing exceptions in "hot" parts of the code.

Consider that if this a performance critical section of your code you may enter it 1,000,000 times a second and a throw probability of 1 in 1,000 may be "rare" but it may result in a unacceptable decrease in performance.

You really have to measure these things for realistic user scenarios and gather data to know if one design or another is going to better (or worth implementing a more complex design) from a performance perspective.

In terms of data, .NET provides performance counters specifically related to the exceptions which can be a helpful diagnostic when faced with performance issues.

Mike Zboray
  • 39,828
  • 3
  • 90
  • 122
1

This really depends on the situation. Try/Catch does generally have more of a performance hit than than an if/else (again, really depends on the situation), but try/catch blocks are also part of good error handling. As a best practice (for better performance and code maintainability) it's good to limit the number of try/catch blocks by putting them at a higher level. For example, if you have a class named "Car" with a "Drive" method and that method calls Car.StartEngine() and Person.FastenSeatBelt() (and assuming an exception is possible in both methods) then instead of having a try/catch inside the StartEngine method and another inside the FastenSeatBelt method, you could have one inside the Drive method and exceptions thrown in the StartEngine or FastenSeatBelt method would bubble-up to the catch block inside the Drive method.

Here's something more to consider when deciding whether to use an if/else or a try/catch. Let's say you have a method ConvertToCamelCase(string). What would you like to do if null is passed for the string parameter? Personally, I'd prefer to have this method throw an ArgumentNullException. Then I would use a try/catch block in the calling method if I needed to log or handle the exception. But, if you decide to return true/false regardless of whether or not the parameter is null, I'd suggest renaming this method to TryConvertToCamelCase(string). This naming convention suggests to the caller that they don't need to worry about exceptions being thrown from this method, because it's going to try and return false if it fails for any reason. The calling method would then use if/else to handle the case when the string cannot be converted to camelCase.

Another thing to consider is whether or not you can gracefully handle an "exception" and continue from the section of code that you are in currently. For example, let's say I have a Windows Form that simply opens a file that the user specified in a text box after clicking "Open." If I was doing the file handling in the event handler of the button click, I would put the code to handle opening the file inside an if statement, with the condition being File.Exists. If the file didn't exist, it would go to the else block and a message box would popup letting the user know that the file didn't exist. But, if the event handler instead used a helper class I created, let's call it "FileHelper" then the "ReadFile" method of FileHelper wouldn't even bother to check if the File Exists, it would just try to open it and if it couldn't a FileNotFoundException would be thrown. Then my button click event handler would catch the exception and alert the user. The reason for this is that the "FileHelper" class has no knowledge of a Form or any user interaction. If the "ReadFile" method can't open the file, there's no way for it to continue, so it's an exception.

The last thing I'd like to mention is to make sure that when you handle an error, it's the error you are expecting. Often, I see developers doing "catch (Exception ex)" and then handling the error by prompting the user. But, using the previous ReadFile method, let's say you're running this as a 32-bit app and it's already consuming 1.9999 GB of it's 2GB limitation, maybe instead of "ex" being a FileNotFoundException, it's really an OutOfMemoryException. Prompting the user by saying "hey buddy, that file doesn't exist" when it really does just adds to a negative user experience (not saying you'd do that, just something I see too often). In stead you can use "catch (FileNotFoundException ex) {...}" or "catch (Exception ex) { if (ex is FileNotFoundException) {...} else {...}}"

IN SUMMARY: Don't be afraid to use try/catch when you need to log or handle an exception, but don't go crazy with try/catch blocks either.

Peter Pompeii
  • 1,415
  • 1
  • 14
  • 16