Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does processing try-catch without any exception thrown not slow down the program at all?

Tags:

java

try-catch

Today I realized something that appeared weird to me: I noticed that when I just do

try {
    doSomething();
} catch (Exception e) {
}

it isn't slower at all than if I just do

doSomething();

So I ran a test and wrote down some quick code to prove what I saw, the code basically just loops over a function called doSomething() lots of times, one time without and one time with try-catch surrounding it. So here's the code to it if you want to test it yourself:

public class Main {

private static final long LOOPS = 1000000L;

public static final void main(String[] args)
{
    System.out.println("Loop without try catch: "+loopWithoutTryCatch(LOOPS));
    System.out.println("Loop with try catch: "+loopWithTryCatch(LOOPS));
}

public static long loopWithoutTryCatch(long loops)
{
    long startTime = System.currentTimeMillis();

    for (long i = 0L; i < loops; i++)
    {
        doSomething();
    }

    return System.currentTimeMillis()-startTime;
}

public static long loopWithTryCatch(long loops)
{
    long startTime = System.currentTimeMillis();

    for (long i = 0L; i < loops; i++)
    {
        try {
            doSomething();
        } catch (Exception e) {
        }
    }

    return System.currentTimeMillis()-startTime;
}

public static void doSomething()
{
    for (int i = 0; i < 250; i++)
    {
        if (i % 3 == 0)
        {
            i++;
        }
    }
}
}

And I received the following output:

Loop without try catch: 375
Loop with try catch: 373

I was surprised so I tested it again and again, but I always got similar results, both ways it runs pretty much in the same time.

And now my question is: Why?

I dont really understand it, as far as I know try-catch writes the resources before usage in some kind of table to later - if any exception is thrown - be able to clean it up and reference to the values it had before the exception occured.

This should take at least some time, shouldn't it? I thought it is maybe because I the random example I choose doesnt represent it properly, and in that specific case in which I tested it it doesnt slow down anything, but that seemed very unlikely to me.

Then I thought maybe it just takes such a tiny amount of time that it isnt noticable with that "few" amount of executions, so I ran the test program again with a total number of 10 million loopings, but what I found just prooved what I had already found: It takes pretty much the same time for both executions.

So is there any logical explanation for that this is the case or just a example-specific behaviour of try-catch?

Thanks for any clarification in advance.

like image 340
flotothemoon Avatar asked Jun 07 '14 17:06

flotothemoon


1 Answers

The "slowness" in throw / catch blocks comes from the process of throwing and catching the exception, not in the process of setting up "traps" for them. When you throw an exception, JVM must

  • Create an instance of an exception
  • Prepare space for the stack trace
  • Populate the stack trace into the prepared space
  • "Unwind" the stack down to the correct place
  • Pass the control to your exception handler.

When none of that is happening, JVM simply sticks a note that an exception handler is available at this level on the stack, and continues executing the actual code.

Making the feature penalty-free was a very important goal for language designers: programmers should not be required to pay for things that they do not use. Otherwise, programmers would be tempted to skip exception handling or go back to the C ways of using status codes in order to save a few CPU cycles here and there, spelling the end to the exceptions as a feature.

like image 149
Sergey Kalinichenko Avatar answered Oct 11 '22 18:10

Sergey Kalinichenko