Brendan Enrick

Daily Software Development

Try Catch Performance in CSharp: A Simple Test Response

I read an interesting little post about a Try Except Performance Test Using Python written by Patrick Altman. As he mentioned, I have also had discussions with people about this exact topic in the past plenty of times. He was testing the performance issue of whether it is better to use a try catch block to handle possible errors or to check for them before they're a problem.

He handled 2 different cases; the success and the failure. Using loops he performed time checks on these to see how long it took. I thought it was very interesting, but the nice question is how does this hold up using C#. So I also wrote a simple little test similar to his. The results are pretty interesting. Keep in mind this just gives some rough estimates on this.

 

The case where the key does not exist:
1,000 iterations:
Try_NotExist(1000) = 00:00:00.0852580
Without_Try_NotExist(1000) = 00:00:00.0000089
Without_Try_NotExist_Not(1000) = 00:00:00.0000089
100,000 iterations:
Try_NotExist(100000) = 00:00:06.1590461
Without_Try_NotExist(100000) = 00:00:00.0006802
Without_Try_NotExist_Not(100000) = 00:00:00.0006799
1,000,000 iterations:
Try_NotExist(1000000) = 00:01:02.8172468
Without_Try_NotExist(1000000) = 00:00:00.0070592
Without_Try_NotExist_Not(1000000) = 00:00:00.0092609

The case where the key does exist:
1,000 iterations:
Try_Exist(1000) = 00:00:00.0000083
Without_Try_Exist(1000) = 00:00:00.0000117
Without_Try_Exist_Not(1000) = 00:00:00.0000117
100,000 iterations:
Try_Exist(100000) = 00:00:00.0006185
Without_Try_Exist(100000) = 00:00:00.0008624
Without_Try_Exist_Not(100000) = 00:00:00.0008492
1,000,000 iterations:
Try_Exist(1000000) = 00:00:00.0088896
Without_Try_Exist(1000000) = 00:00:00.0086661
Without_Try_Exist_Not(1000000) = 00:00:00.0097892

As you can see here my results are somewhat similar to the findings Patrick found. If it is going to fail often at all you're much better off checking for the error before it fails because of how immense the difference between handling the error and not is. However if pretty much every time the code will succeed without any errors, you're better off with the try-catch block by a very small amount. The fact that it is only a small amount better tells me that I am much better off checking for an error than I am using a try-catch block to trap the error.

And so you can try for yourself or inform me of any errors I've made I'll include my code.

using System;
using System.Diagnostics;
using System.Text;

namespace Try_Catch_Performance
{
    class Program
    {
        private static int[] x = { 0 };
        private static int ExistIndex = 0;
        private static int NotExistIndex = 1;

        private static void Try_NotExist(int iterations)
        {
            Stopwatch st = new Stopwatch();
            st.Start();
            for (int i = 0; i < iterations; i++)
            {
                try
                {
                    int y = x[NotExistIndex];
                }
                catch (Exception)
                {
                }
            }
            st.Stop();
            Console.WriteLine("Try_NotExist({0}) = {1}", iterations, st.Elapsed);
        }

        private static void Without_Try_NotExist(int iterations)
        {
            Stopwatch st = new Stopwatch();
            st.Start();
            for (int i = 0; i < iterations; i++)
            {
                if (x.Length > NotExistIndex)
                {
                    int y = x[NotExistIndex];
                }
            }
            st.Stop();
            Console.WriteLine("Without_Try_NotExist({0}) = {1}", iterations, st.Elapsed);
        }

        private static void Without_Try_NotExist_Not(int iterations)
        {
            Stopwatch st = new Stopwatch();
            st.Start();
            for (int i = 0; i < iterations; i++)
            {
                if (!(x.Length <= NotExistIndex))
                {
                    int y = x[NotExistIndex];
                }
            }
            st.Stop();
            Console.WriteLine("Without_Try_NotExist_Not({0}) = {1}", iterations, st.Elapsed);
        }

        private static void Try_Exist(int iterations)
        {
            Stopwatch st = new Stopwatch();
            st.Start();
            for (int i = 0; i < iterations; i++)
            {
                try
                {
                    int y = x[ExistIndex];
                }
                catch (Exception)
                {
                }
            }
            st.Stop();
            Console.WriteLine("Try_Exist({0}) = {1}", iterations, st.Elapsed);
        }

        private static void Without_Try_Exist(int iterations)
        {
            Stopwatch st = new Stopwatch();
            st.Start();
            for (int i = 0; i < iterations; i++)
            {
                if (x.Length > ExistIndex)
                {
                    int y = x[ExistIndex];
                }
            }
            st.Stop();
            Console.WriteLine("Without_Try_Exist({0}) = {1}", iterations, st.Elapsed);
        }

        private static void Without_Try_Exist_Not(int iterations)
        {
            Stopwatch st = new Stopwatch();
            st.Start();
            for (int i = 0; i < iterations; i++)
            {
                if (!(x.Length <= ExistIndex))
                {
                    int y = x[ExistIndex];
                }
            }
            st.Stop();
            Console.WriteLine("Without_Try_Exist_Not({0}) = {1}", iterations, st.Elapsed);
        }

        static void Main(string[] args)
        {
            Console.WriteLine("The case where the key does not exist:");
            Console.WriteLine("1,000 iterations:");
            Try_NotExist(1000);
            Without_Try_NotExist(1000);
            Without_Try_NotExist_Not(1000);
            Console.WriteLine("100,000 iterations:");
            Try_NotExist(100000);
            Without_Try_NotExist(100000);
            Without_Try_NotExist_Not(100000);
            Console.WriteLine("1,000,000 iterations:");
            Try_NotExist(1000000);
            Without_Try_NotExist(1000000);
            Without_Try_NotExist_Not(1000000);

            Console.WriteLine("The case where the key does exist:");
            Console.WriteLine("1,000 iterations:");
            Try_Exist(1000);
            Without_Try_Exist(1000);
            Without_Try_Exist_Not(1000);
            Console.WriteLine("100,000 iterations:");
            Try_Exist(100000);
            Without_Try_Exist(100000);
            Without_Try_Exist_Not(100000);
            Console.WriteLine("1,000,000 iterations:");
            Try_Exist(1000000);
            Without_Try_Exist(1000000);
            Without_Try_Exist_Not(1000000);
        }
    }
}

Happy Error Checking!

Loading