Error Handling

I l @ ve RuBoard

Error handling is a fact of life for applications, but that doesn't mean it should slow you down. Here are a few tips for avoiding potential error-handling- related performance issues.

On Error Goto and On Error Resume Next vs. Exceptions

The On Error statement should be familiar to Visual Basic developers. After all, it was the only error-handling mechanism built into previous versions of Visual Basic. Visual Basic .NET does provide these error-handling constructs, but they're for backward compatibility only. Structured exception handling is now the order of the day. Even though it's not necessarily obvious, just adding On Error to a method will result in your code running more slowly, regardless of whether errors are actually occurring. To see why this is true, let's compare two methods :

 PrivateSubTryCatch_Simple() Try Console.Write("This ") Console.Write("is ") Console.Write("a ") Console.Write("good ") Console.WriteLine("test.") CatchexAsException Console.WriteLine("Thecommandfailed") EndTry EndSub PrivateSubOnError_Simple() OnErrorResumeNext Console.Write("This ") Console.Write("is ") Console.Write("a ") Console.Write("bad ") Console.WriteLine("test.") EndSub 

Someone comparing the two methods might think that the OnError_Simple method is more efficient merely because it appears to contain less code. This couldn't be further from the truth. The compiled code can be quite different. I'll leave the exercise of checking out the actual MSIL output to you, but I've grabbed some information that demonstrates , in part, what the problem is:

 .methodprivatestaticvoidTryCatch_Simple()cilmanaged { //Codesize77(0x4d) ... }//endofmethodModule1::TryCatch_Simple .methodprivatestaticvoidOnError_Simple()cilmanaged { //Codesize180(0xb4) ... }//endofmethodModule1::OnError_Simple 

What should you make of these two MSIL examples? First, notice how much longer OnError_Simple is. At the top of each example, you'll see a comment that describes the code size of each method. The OnError_Simple method weighs in at 180 bytes, while the TryCatch_Simple method weighs in at 77 bytes (less than half). But of course, this doesn't tell the whole story. Remember, I said that less code does not always run faster, but here it definitely does. To help illustrate this, I created a sample application called OnErrorPerformance (one of this chapter's samples files) using both the TryCatch_Simple and OnError_Simple methods described above and two similar, but larger, methods ( essentially duplicating the internal code several times). The numbers are interesting:

 TestNameTryCatchOnErrorDiff ----------------------------------------------- SimpleTest1602192250342564.0% SimpleTest1602192230315169.6% SimpleTest1602192240328866.7% SimpleTest1502055240328862.5% LongerTest32043841261726225.4% LongerTest32043841271739925.2% LongerTest33045211241698826.6% LongerTest32043841251712525.6% 

You can see that using On Error is about 25 percent slower than using Try Catch for the "Simple Test". Not too bad, right? Well, as you can see, it gets worse. In fact, it gets much worse. The larger the method, the worse the effect on performance. The larger method tests demonstrate that admirably. The OnError_Longer method is almost four times slower than the TryCatch_Longer method. Wow.

Using the old Visual Basic style of error handling is terrible for performance. Incidentally, this was also true in Visual Basic 6.0. Essentially, On Error injects a lot of code into a method to perform its magic. This results in your method containing a placeholder for each physical line of code, similar to using a line label. The method is then enclosed in one Try...Catch , and when an exception occurs, the line to go to is determined by a switch clause and the last saved location. As you might expect, this results in a large amount of overhead for such a little statement. The reality is that this is one of the most inefficient forms of error handling you can use. (Of course, some industrious individual might prove us wrong ”someone can always come up with a more inefficient solution.)

Burn this into your brain before you go on to the next section: exception handling good. On Error bad. Really bad.

Exception Handling Best Practices

I talked a lot about proper exception handling in Chapter 2, and I don't want to belabor the subject here. I will, however say this: exceptions should be exceptional. Exception handling is fairly expensive. Granted, when no exceptions are being thrown, there is little impact on performance. But if you throw exceptions regularly in your code, you'll likely experience significant performance degradation. Two rules should apply to exception handling:

  • Never throw an exception unless something truly exceptional occurs.

  • Never catch an exception if all you'll do is rethrow it.

OK, everyone clear? Good. Let's move on.

I l @ ve RuBoard


Designing Enterprise Applications with Microsoft Visual Basic .NET
Designing Enterprise Applications with Microsoft Visual Basic .NET (Pro-Developer)
ISBN: 073561721X
EAN: 2147483647
Year: 2002
Pages: 103

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net