The Exception Penalty In C#

As a C# Performance Architect, your job is to create solution architectures that provide the best possible performance for your business or organization. And to do your job well, you’ll need a solid understanding of basic C# code optimizations.

In this post, we’ll look at the overhead of throwing and catching exceptions in your code. Catching exceptions will slow down your code a lot, so it’s very important to have a clear understanding of your error-handling strategy.

Take a look at the following code.

static void Main(string[] args)
{
    string input = GetInputData();
    try {
        int result = int.Parse(input);
        // do something with result
    }
    catch (FormatException) {
        // suppress the exception
    }
}

I’m calling the method GetInputData() which returns a string. This can be either a valid or invalid integer, so I’m parsing the data using int.Parse() and catch any FormatException that might get thrown.

But wait! There’s another way of doing this.

Check out the following code:

static void Main(string[] args)
{
    string input = GetInputData();
    int result = -1;
    bool valid = int.TryParse(input, out result);
    if (valid) {
        // do something with result
    }
}

Pretty much the same code, right? Not much difference between the two.

Think again! I’ve coded a quick benchmark to compare the two parse methods. Take a look:

Did you see the results? The code that catches the exception is 121 times slower than the code that uses int.TryParse().

That’s a massive difference. The reason is that exceptions are meant for diagnostics and debugging. When you throw an exception, the .NET runtime takes a snapshot of the thread state and stack trace, and then unwinds the stack until it encounters a matching catch block. This process is really slow, on average it takes about a microsecond. Almost an eternity at CPU scale.

To avoid this slowdown, stick to these three tips:

  • Don’t use exceptions for control flow (duh)
  • Use the TryXXX methods when parsing dirty input data
  • Never suppress exceptions in mission-critical code

Basically, only throw exceptions if you want code execution to stop, period.

 

 

Would you like to know more? I’ve created a series of blog posts on C# performance optimization. Each post is based on content from my courses and from actual techniques I’ve used in the field.

Take a look: