.net - with - zero cost exceptions c++




Performance Considerations for throwing Exceptions (8)

I have come across the following type of code many a times, and I wonder if this is a good practice (from Performance perspective) or not:

try
{
    ... // some code
}
catch (Exception ex)
{
    ... // Do something
    throw new CustomException(ex);
}

Basically, what the coder is doing is that they are encompassing the exception in a custom exception and throwing that again.

How does this differ in Performance from the following two:

try
{
    ... // some code
}
catch (Exception ex)
{
    .. // Do something
    throw ex;
}

or

try
{
    ... // some code
}
catch (Exception ex)
{
    .. // Do something
    throw;
}

Putting aside any functional or coding best practice arguments, is there any performance difference between the 3 approaches?


When you need to distinguish one exception from the others somehow. That's it, really. Of course, you could create an exception class that takes an enum to distinguish its cause, also.

This is really easy to see when you want to pass extra information with the exception. The only reason to pass that information is if you want to be able to get that information later, and so you'll want to know the type so you can retrieve the information from that type and not others.

In C++, and perhaps some other languages, you might also typedef an exception. This would allow for type distinguishing, and possibly future conversion to a custom class.


@Brad Tutterow

The exception is not being lost in the first case, it is being passed in to the constructor. I will agree with you on the rest though, the second approach is a very bad idea because of the loss of stack trace. When I worked with .NET, I ran into many cases where other programmers did just that, and it frustrated me to no end when I needed to see the true cause of an exception, only to find it being rethrown from a huge try block where I now have no idea where the problem originated.

I also second Brad's comment that you shouldn't worry about the performance. This kind of micro optimization is a HORRIBLE idea. Unless you are talking about throwing an exception in every iteration of a for loop that is running for a long time, you will more than likely not run into performance issues by the way of your exception usage.

Always optimize performance when you have metrics that indicate you NEED to optimize performance, and then hit the spots that are proven to be the culprit.

It is much better to have readable code with easy debugging capabilities (IE not hiding the stack trace) rather than make something run a nanosecond faster.

A final note about wrapping exceptions into a custom exception... this can be a very useful construct, especially when dealing with UIs. You can wrap every known and reasonable exceptional case into some base custom exception (or one that extends from said base exception), and then the UI can just catch this base exception. When caught, the exception will need to provide means of displaying information to the user, say a ReadableMessage property, or something along those lines. Thus, any time the UI misses an exception, it is because of a bug you need to fix, and anytime it catches an exception, it is a known error condition that can and should be handled properly by the UI.


I can't see there being a big performance difference between your two options. Most of the work is locating and reading the file so in both cases you have to do that. What might be useful is caching the result if you don't expect the user add/remove this file while the application is running. So you might do something like

private static Dictionary<Uri, ResourceDictionary> _uriToResources =
  new Dictionary<Uri, ResourceDictionary>();
public static ResourceDictionary GetResourceDictionary(Uri uri)
{
  ResourceDictionary resources;
  if (_uriToResources.TryGetValue(uri, out resources))
  {
    return resources;
  }

  try
  {
     resources = (ResourceDictionary)Application.LoadComponent(uri);
  }
  catch
  {
     // could prompt/alert the user here.
     resources = null; // or an appropriate default.
  }

  _uriToResources[uri] = resources;
  return resources;
}

This would prevent you from repetitively trying to load a resource that does not exist. Here I return a null object but it may be better to use some default as a fallback.


I'm a bit of a minimalist and will only create a custom exception if there is calling code that must explicitly react to the particular condition that occured. For all other situations I'll use the most appropriate .NET library exception. E.g. ArgumentNullException, InvalidOperationException


Obviously you incur in the penalty of creating new objects (the new Exception) so, exactly as you do with every line of code that you append to your program, you must to decide if the better categorization of exceptions pays for the extra work.

As a piece of advice to make that decision, if your new objects are not carrying extra information about the exception then you can forget constructing new exceptions.

However, in other circumstances, having a hierarchy of exceptions is very convenient for the user of your classes. Suppose you're implementing the Facade pattern neither of the so far considered scenarios is good:

  1. is not good that you raise every exception as an Exception object because you're losing (probably) valuable information
  2. is not good neither to raise every kind of object that you catch because doing so you're failing in creating the facade

In this hypothetical case, the better thing to do is to create a hierarchy of exception classes that, abstracting your users from the inner complexities of the system, allows them to know something about the kind of exception produced.

As a side note:

I personally dislike the use of exceptions (hierarchies of classes derived from the Exception class) to implement logic. Like in the case:

try {
        // something that will raise an exception almost half the time
} catch( InsufficientFunds e) {
        // Inform the customer is broke
} catch( UnknownAccount e ) {
        // Ask for a new account number
}

Sometimes you want to hide the implementation details of a method or improve the level of abstraction of a problem so that it’s more meaningful to the caller of a method. To do this, you can intercept the original exception and substitute a custom exception that’s better suited for explaining the problem.

Take for example a method that loads the requested user’s details from a text file. The method assumes that a text file exists named with the user’s ID and a suffix of “.data”. When that file doesn’t actually exist, it doesn’t make much sense to throw a FileNotFoundException because the fact that each user’s details are stored in a text file is an implementation detail internal to the method. So this method could instead wrap the original exception in a custom exception with an explanatory message.

Unlike the code you're shown, best practice is that the original exception should be kept by loading it as the InnerException property of your new exception. This means that a developer can still analyze the underlying problem if necessary.

When you're creating a custom exception, here's a useful checklist:

• Find a good name that conveys why the exception was thrown and make sure that the name ends with the word “Exception”.

• Ensure that you implement the three standard exception constructors.

• Ensure that you mark your exception with the Serializable attribute.

• Ensure that you implement the deserialization constructor.

• Add any custom exception properties that might help developers to understand and handle your exception better.

• If you add any custom properties, make sure that you implement and override GetObjectData to serialize your custom properties.

• If you add any custom properties, override the Message property so that you can add your properties to the standard exception message.

• Remember to attach the original exception using the InnerException property of your custom exception.


What factors should be taken into consideration when writing a custom exception class?

Questions to ask yourself:

  1. Who will be catching it? If no one, then you don't really need a custom exception.
  2. Where will you be throwing it? Is there enough context readily available, or will you need to catch and re-throw several times before the exception is useful to the final catcher?
  3. Why are you throwing it? Because you caught an exception and need to attach additional information? Because you encountered an unrecoverable error in some data, and need to communicate the specifics back to client code? Because you like throwing things?
  4. What is the exception? Not what caused it but what is it from the perspective of the catcher? Something they can fix and retry? Something they should never retry? Something they should notify the user about? Something they should attach context information to and then re-throw? What determines the information you'll need to pass along, if any...

Precepts:

  1. Do not waste time on custom exceptions that will never be caught.
  2. Do not "double up" exceptions: each custom exception type should have a well-defined case where it can and should be caught; exceptions that don't match should be broken out into their own custom types (rather than, say, forcing the catcher to build conditional logic into a single catch() clause).
  3. Unless you have a good reason not to, always allow attaching an inner exception / data from a previously-caught exception. Losing context is rarely helpful.

Why Re-throw Exceptions?

Rethrowing the same exception is useful if you want to, say, log the exception, but not handle it.

Throwing a new exception that wraps the caught exception is good for abstraction. e.g., your library uses a third-party library that throws an exception that the clients of your library shouldn't know about. In that case, you wrap it into an exception type more native to your library, and throw that instead.





performance