Welcome to MSDN Blogs Sign in | Join | Help

Donkblog

Adventures into the world of amateurgramming. I'll leave the programming to the professionals.
The Dangers Of Exception Based Logic Part 1 - Parsing Integers

Exception based logic is one of those things that actually makes me cringe when I see it.  Often times it is really easy to avoid like in the case below.  Believe it or not, exceptions in .NET aren't cheap and shouldn't be taken for granted.

 

Exception Based Logic:     14-19ms

Try Function Based Logic: 0ms

 

static void Main(string[] args)
{
    using (new QuickTimer("Exception Based Logic"))
    {
         for (int i = 0; i < 10; i++)
         {
             try
             {
                 int j = Int32.Parse("a");
             } catch (Exception ex)
             {
                 Console.WriteLine("Error");
             }
         }
    }

    using (new QuickTimer("Try Function Based Logic"))
    {
         for (int i = 0; i < 10; i++)
         {
              int j = 0;
              if (!Int32.TryParse("a",out j))
              {
                  Console.WriteLine("Error");
              }
         }
      }
}
Posted: Monday, March 03, 2008 6:59 AM by Brandon Turner
Filed under: ,

Comments

Jeff said:

instead of what you have above, what about

try

{

  int j = Int32.Parse("a");

}

catch

{

  Console.WriteLine("Error");

}

without passing the exception, is that as expensive?

# March 3, 2008 11:40 AM

Brandon Turner said:

I don't see any speed difference whether I pass the exception or not.  I would *think* since I don't use the exception the compiler just optimizes it out.  

# March 3, 2008 11:53 AM

Timothy Fries said:

I'd doubt the compiler performs that sort of optimization, especially in this case, where the code that's creating and throwing the exception exists in a library that's already been compiled to MSIL.  In this scenario, the only possible player that could optimize anything would be the JIT, and the JIT has no way of knowing whether every call the program will make to the method will result in the exception object being ignored, since the JIT doesn't have an overall picture of the program, only what needs to be compiled *right now*, and some information about what's been compiled in the past.

Plus there's the what-ifs -- What if the construction of the exception object has side effects? Optimizing the exception away would change the meaning of the code.  What if someone uses reflection or a delegate to call a method that was 'optimized' because it was only statically used in places where the object was ignored, but in the dynamic call case, they actually want the exception object?  The code's contract was again broken by the optimization, but from the other side this time.

And that's not even addressing the real possibility (not that I've measured it) that a good portion of the performance issues with Exceptions involves unwinding the stack, which is something that would need to be done, even in the case where the exception object itself (and the expensive actions it entails, like building the stack trace) could be optimized away.

# March 3, 2008 1:11 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

  
Enter Code Here: Required

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Page view tracker