Sign In
Posted By: Donald Adu -Poku | May 14th @ 6:05 PM

In the .NET programming sphere, code that feels like it might generate exceptions is put in a try{} block which would sound an alarm whenever one of these occur during execution. This "thrown" exception is caught by a catch {} block and handled appropriately.

Even though this feature makes our programming lives easier it has a drawback being a certain reduction in performance. This means that the number of exceptions thrown is inversely proportional to your application's performance. There are other operations in .NET that have similar effects, like boxing and unboxing of value types.

I ran a little test to check this out. I intentionally produced an exception and handled it while measuring the time it took to do this.

 

            int[] Array = null; //not instantiated

            Stopwatch watch = new Stopwatch();

 

            try

            {

                watch.Start();

                Array[0] = 1;//exception thrown

            }

            catch (NullReferenceException)

            {

                watch.Stop();

                Console.WriteLine(watch.ElapsedMilliseconds +"ms");

            }

            watch.Reset();

            Console.ReadLine();

      

I got 23ms as an average of three executions. To serve as comparison I used a foreach construct to iterate a numeric array.

int[] numArray = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

            Stopwatch watch = new Stopwatch();

 

            watch.Start();

            foreach (int number in numArray)

            {

                Console.WriteLine(number);

            }

            watch.Stop();

 

            Console.WriteLine();

            Console.WriteLine(watch.ElapsedMilliseconds + "ms");

            Console.ReadLine();

 

I got 4ms as an average of three executions.

With these results I would say that the process of throwing and handling exceptions is quite slow.

But that alone does not justify avoiding them. Exceptions should be thrown when needed. Your code would be better off having just the right quantity of exception throwing and handling structures than none, which could bite you pretty hard at runtime.

Exception-safe code is your best bet to minimizing the number of exceptions thrown instead of throwing them at the slightest provocation. Take a look at this code:

 

public string[] Getnames()

        {

            string[] array = null;

            if (/* new names are available */)

            {

                //populate the array with names

                return array;

            }

            return array;

        }

public void PrintNames(string[] nameArray)

        {

            foreach (string name in nameArray)

            {

                //print the name

            }

        }

The PrintNames method could unnecessarily throw an ArgumentNull exception if there are no names to populate the string array.

The problem between these two methods is the state of the return type of GetNames() .If there are no names when GetNames() is called then the returned array would be null.

string[] array = null;

         .............

            return array;

 

In order to avoid an ArgumentNull exception when calling PrintNames() a defualt array could be returned when there aren’t any new names to populate the array with.The reifned code would look like this:

 

public string[] Getnames()

        {

            string[] array = null;

            if (/* names are available */)

            {

                //populate the array with names

                return array;

            }

            return new string[0];

        }

 

 

Using default states over null(the almighty) saves you some exception hassle ,the trade-off though is memory resource.Little changes like this definitely help make your code better .Happy coding Smiley

Tags:
Rating:
0
0
I wonder how many people actually think of things like this...I'm glad someone does though Wink
littleguru
littleguru
(microsoft student partnering)++
The deal is the following: only putting a try-catch(-finally) into your code doesn't make your application slower; and that's good! If you throw an exception that takes some time because the stack needs to be walked etc.

Therefore exceptions shouldn't be used for program flow; that means that you don't use exceptions to exit a method or branch or similar... there are other constructs like return, if etc for that. Never use exceptions for that.

If you follow these guidelines you only throw exceptions if you reach a state (in your app) that's not valid. Like you tried to access something that's null or you open a file that's not existent etc. In other words: when you throw an exception something got terribly wrong and you can't do much about it. In that case it isn't important if your exceptions take like a few milliseconds more because they happen very rare and therefore don't influence your performance much.

If you take for example the exception that's thrown when you open a file that doesn't exist. You can always avoid that by checking if the file exists in the first place. There are methods to do that. The same applies to null reference exceptions. You can always check if the array (to take Donald's example) has been initialized. If it hasn't perhaps you can only return from the method with a false or something similar...

Exception might include user input to fix the problem or the application might completely crash; but that's fine!

There's also another point with exceptions: people think they are evil and that they need to catch all of them. Never do that. Always only catch what you can handle. All the other stuff don't catch; even if your application crashes. Try to understand what crashed the application and see then if you could handle the crash somehow; if you can't don't do anything.
littleguru
littleguru
(microsoft student partnering)++
Btw., Donald, if you test something like this you need to run it more often... if you run such tests only 3 times there could be a lot of things that influence your testing; like another app could run at higher priority and steal CPU time etc. Also you should always specify on what system you tested; otherwise people don't know how how to put the numbers in relation.
Christian mentioned the most important point - only catch what you can handle. All too often I see people catching Exception which is just very , very bad.

I would run something to gather a nice variation of data a few hundred times and perform other forms of statistical analysis on that data to see a true representation of the values collected (e.g. variance, std dev).

The reason I tend to run things so many times, is because of the scheduler - as the system can be allowing other higher priority processes to utilize the CPU of which their is a varying number at any time. 

I think what has been touched on is actually pretty interesting as it brings up the whole Exceptions vs Error code argument, the latter of which tends to be preferred in systems code for the reason Christian mentioned - throwing exceptions IS expensive.

Another one to watch out for is not not rethrow an exception by saying something like throw ex; rather just put a straigth throw; to preserve the call stack.

In general I think Christian mentioend the things I would of but I've thrown in a few others as its a pretty interesting area in terms of API design.
littleguru
littleguru
(microsoft student partnering)++
Interesting that you mention the error code vs exception discussion. I'm really much on the exception side there. Because my idea is to throw an exception only if you are already doomed. In that case the few ms that you loose don't count... I, also don't like error codes because you can simply ignore them. That's what often happens in older applications and then results in weird crashes that nobody understands anymore...
Actually, If you start using Agile methodologies and Test Driven Development, You eliminate all those NullReferenceExceptions, ArgumentExceptions etc. Wink
I have blogged on it Smiley (the posts have external links too associated with it)