The Dangers Of Exception Based Logic Part 2 - Filesystem Interaction

I have often time seen filesystem interaction code that heavily depends on exception handling.  Code out in the wild rarely exposes this problem in such a trivial way as my example code below, but just wanted to give another example.

 

 

Exception Based Logic: 14-21ms
Preemptive Error Checking Based Logic: 0ms

 

 static void Main(string[] args)
{
    using (new QuickTimer("Exception Based Logic"))
    {
        for (int i = 0; i < 10; i++)
        {
            try
            {
                string userInputPath = @"C:\not\a\real\path\foo\bar.txt";
                File.WriteAllText(userInputPath, "Some String To Write");
            } catch (Exception ex)
            {
                Console.WriteLine("Error");
            }
        }
    }

    using (new QuickTimer("Preemptive Error Checking Based Logic"))
    {
        for (int i = 0; i < 10; i++)
        {
            string userInputPath = @"C:\not\a\real\path\foo\bar.txt";

            if (!File.Exists(userInputPath))
            {
                Console.WriteLine("Error");
                continue;
            }

            File.WriteAllText(userInputPath, "Some String To Write");
        }
    }
}

Comments

  • Anonymous
    March 04, 2008
    What about putting the loop within the try block?What time does that give?
  • Anonymous
    March 04, 2008
    I can't put the loop inside the try block, because once File.WriteAllText is executed for the first time an exception of DirectoryNotFoundException will be thrown and it will be outside the loop.I am mostly just using the loop to show how this problem can scale.  If in our real code the loop was not needed, there was would be a very tiny speed difference.  Though if that piece of code is executed a lot and the program is half a million lines of code; chances are if it happens one place then it happened many places.
  • Anonymous
    March 04, 2008
    Good to read the reality .. and most of the decisions are based on the logical thinking where we can use the TRY..CATCH..Secondly, can you share the code that you have written for QuickTimer Class. All these days am using the following code to get the time span for executing any code.Method 1)           long lStart = DateTime.Now.TimeOfDay.Ticks;           for (int intCnt = 0; intCnt < intLstVal; intCnt++)           {               ExecuteSomeMethod(10);           }           long lEnd = DateTime.Now.TimeOfDay.Ticks;           cs.WriteLine("Started at .. " + lStart.ToString() + " and ended at .. " + lEnd.ToString());           long lTmDiff = lEnd - lStart;           cs.WriteLine("The MilliSeconds at the end is .. " + (lTmDiff / 10000).ToString() + " MilliSeconds");Method 2) Using the TimeSpan           TimeSpan tsStart = DateTime.Now.TimeOfDay;           for (int intCnt = 0; intCnt < intLstVal; intCnt++)           {               cs.Write(intCnt.ToString() + "-");               DoObjectTest(10);           }           double dMs = DateTime.Now.TimeOfDay.Subtract(tsStart).TotalMilliseconds;           cs.WriteLine("The time in MilliSeconds to execute the code block is .. " + dMs.ToString() + " MilliSeconds");Please comment or suggest any new methods to have more accurate time details.Thanks for reading.
  • Anonymous
    March 05, 2008
    The comment has been removed
  • Anonymous
    March 05, 2008
    @dskcheckI just use http://jcheng.wordpress.com/2007/10/23/code-sample-quicktimer-2/@TimothyYou are right.  There are still tons of cases where we need to have try/catch for things way out of our control.  But it doesn't mean we have to depend on them for things that we could figure out faster on our own.