Chinh Do

Try/Catch Blocks Can Hurt Performance

First time here? Check out my greatest hits or look around in the archives, and consider subscribing to the latest posts via RSS or email. I am also on Twitter and Google Plus. Thanks for visiting.
26th February 2008

Try/Catch Blocks Can Hurt Performance

Over at Programmers Heaven.com, there’s an interesting article on the potential performance impact of try/catch blocks. The article concluded that the average cost of a try/catch block is essentially nothing (sorry there’s no author information on the post so I couldn’t tell who wrote it), and that .NET/C# programmers should not think twice about using try/catch blocks.

The author is right that a try/catch block has essentially zero cost. However, like most coding performance issues, exceptions and try/catch blocks do not have performance implications until they occur in some type of loop. Something like this will do the job:

Dictionary<int, int> numbers = new Dictionary<int, int>();
Stopwatch w = new Stopwatch();
w.Start();
int notFound = 0;
for (int i = 1; i <= 1000000; i++)
{
    try
    {
        int value = numbers[i];
    }
    catch (KeyNotFoundException)
    {
        notFound++;
    }
}

w.Stop();
Console.WriteLine(notFound);
Console.WriteLine("Elapsed: " + w.ElapsedMilliseconds + ".");

In the block of code above, I am trying to find the number of integers from 1 to 1,000,000 that are not in the numbers dictionary. One way to do it is to try to access the dictionary item by key. Since the Dictionary class will throw a KeyNotFoundException if the key is not found, that’s how I am going to know whether each value is in the dictionary or not.

Well, let’s just see how long that code takes to run. On my virtual PC it took … hold on a sec, it’s till running… still waiting… not quite there yet… finally: 101031 (101 seconds).

If you have any doubt, this is the type of try/catch block or exception handling they advice against. :-)

The above logic, when implemented correctly without using a try/catch block, took only 10 milliseconds. Yes, that’s not a typo: 10 milliseconds. Oh, only about 10,000 times faster.

Here’s the correct code:

Dictionary<int, int> numbers = new Dictionary<int, int>();

Stopwatch w = new Stopwatch();
w.Start();

int notFound = 0;
for (int i = 1; i <= 1000000; i++)
{
    if (! numbers.ContainsKey(i))
    {
        notFound++;
    }
}

w.Stop();
Console.WriteLine(notFound);
Console.WriteLine("Elapsed: " + w.ElapsedMilliseconds + ".");

So, do consider performance impact when using exceptions and try/catch blocks. Avoid using exception handling to implement normal program flow. Here are some links on exception handling best practices in .NET:

kick it on DotNetKicks.com

posted in Dotnet/.NET - C#, Programming | 28 Comments

25th February 2008

Finds of the Week – February 24, 2008

.NET Programming

WCF

Something Different

  • Learning to Smoke. It’s not permitted. It pisses people off. It makes you puke. It confuses you, and it brings clarity. It makes you an outcast, and it helps you meet wonderful strangers. Lessons from a man who did the unthinkable.

posted in Dotnet/.NET - C#, Programming | 0 Comments

18th February 2008

Finds of the Week – February 17, 2008

.NET

Software and Tools

  • Looking for a free sharepoint host? You can get a free sharepoint account with 5MB disk space, 5 users from Frontpages Web Hosting Network. Link is here.

Gadgets

  • The HD format war is over. I am waiting for Blu-ray players go go down to the $150 range before I’ll get one.

And Now, Something A Little Different

posted in Dotnet/.NET - C#, HDTV, Programming, Technology | 0 Comments

13th February 2008

Finds of the Week – February 11, 2008

Finds of the Week is on break for the Lunar New Year/Tet holiday. The series will resume next week.

posted in Dotnet/.NET - C#, Programming, Technology | 0 Comments

13th February 2008

Not So Great Experience with Verizon FIOS Web Support

My Verizon FIOS router (ActionTech MI424WR) died the other day. So I tried to contact Verizon Online tech support to get a replacement. Well, they certainly don’t make it easy.

On the support web site page, there are two methods to obtain support: Email and Phone. Upon further examination, Email support is there mostly for show, because it’s nothing more than an automated system, very good at sending out useless canned responses such as this:

 image

Note the disclaimer at the top stating that the replies are automated. Why??? I am already on the web site, why not just display the help result right there? What are they thinking?

All is not lost, because there’s still the Phone option right? Well this is what I got after clicking on it:

Verizon Online

I tried again on another computer running Windows 2003 and it looked like it was trying harder this time, but it didn’t quite make it, because it kept on checking forever to see if "Quick Support" is installed:

image 

By the way, if you are looking for the direct number for Verizon FIOS tech support, it is 888-553-1555. I called and was provided the answer I was looking for in about 10 minutes.

posted in Technology | 3 Comments

6th February 2008

Put GetOrdinal Method to Good Use

How often do you see DataReader code that looks like this?

using (IDataReader dr = cmd.ExecuteNonQuery())
{
    while (dr.Read())
    {
        int orderId = dr.GetInt32(0);
        string customerId = dr.GetString(1);
        int employeeId = dr.GetInt32(2);
        DateTime orderDate = dr.GetDateTime(3);
        double freight = dr.GetDouble(4);

        // do stuff
    }

    dr.Close();
}

If that looks like your code, you are not alone :-). Try searching codesearch.google.com for the following:

lang:c# (reader|dr)\.GetInt32\(

codesearch google

With the above code, anytime the order of columns in the SQL statement or stored procedure changes, the code is broken. And if you have lots of columns to read from, it’s a real nightmare to maintain the indexes.

The next time you write another DataReader loop, consider doing it this way instead:

using (IDataReader dr = cmd.ExecuteNonQuery())
{
    int ORDER_ID = dr.GetOrdinal("OrderID");
    int CUSTOMER_ID = dr.GetOrdinal("CustomerID");
    int EMPLOYEE_ID = dr.GetOrdinal("EmployeeID");
    int ORDER_DATE = dr.GetOrdinal("OrderDate");
    int FREIGHT = dr.GetDecimal("Freight");

    while (dr.Read())
    {
        int orderId = dr.GetInt32(ORDER_ID);
        string customerId = dr.GetString(CUSTOMER_ID);
        int employeeId = dr.GetInt32(EMPLOYEE_ID);
        DateTime orderDate = dr.GetDateTime(ORDER_DATE);
        double freight = dr.GetDouble(FREIGHT);

        // do stuff
    }

    dr.Close();
}

Using GetOrdinal makes the code much more readable and maintainable. You are calling GetOrdinal just once for each column, any performance penalty is insignificant compared to the benefits. Be careful not to put the GetOrdinal code inside the while block as that will unnecessarily slow you down (about 3% according to this article).

kick it on DotNetKicks.com

posted in Dotnet/.NET - C#, Programming, Tips | 2 Comments

5th February 2008

Finds of the Week – February 3, 2007

.NET

Software/Tools

Windows Mobile – Pocket PC

  • Looks like Google has fixed the problems that were plaguing Gmail IMAP on Windows Mobile devices. Read the blog entry from the official Gmail Blog here. And here’s a related article from PC World: Google fixes Gmail IMAP problem on Windows Mobile.
  • Viigo is a free RSS reader for Windows Mobile. I have not really used it that much but it seems to work ok.

    Viigo RSS Reader for Windows Mobile 

  • Skyfire is another promising Windows Mobile browser currently in private beta. Via Engadget.

  • If you have a Samsung Windows Mobile device, try the included PicSel browser. Here’s a review of Picsel browser, with a lot of useful how-to information included. By Tam Hanna.

And Now, For Something A Little Different

Nano

posted in Dotnet/.NET - C#, Gmail IMAP, Programming, Software/tools, Technology, Windows Mobile / Pocket PC | 0 Comments