Why adding a try block makes the program faster?

exception, java, performance, try-catch

Solution

When you have multiple long running loops in the same method, one can trigger the optimisation of the whole method with unpredictable results on the second loop. One way to avoid this is;

- to give each loop its own method

- run the tests multiple times to check the result is re-producible

- run the test for 2 - 10 seconds.

You will see some variation and sometimes the results are inconclusive. i.e. variation is higher than the difference.

public class Test {
    int value;

    public int getValue() {
        return value;
    }

    public void reset() {
        value = 0;
    }

    // Calculates without exception
    public void method1(int i) {
        value = ((value + i) / i) << 1;
        // Will never be true
        if ((i & 0xFFFFFFF) == 1000000000) {
            System.out.println("You'll never see this!");
        }
    }

    public static void main(String[] args) {
        Test t = new Test();
        for (int i = 0; i < 5; i++) {
            testWithTryCatch(t);
            testWithoutTryCatch(t);
        }
    }

    private static void testWithoutTryCatch(Test t) {
        t.reset();
        long l = System.currentTimeMillis();
        for (int j = 0; j < 10; j++)
            for (int i = 1; i <= 100000000; i++)
                t.method1(i);

        l = System.currentTimeMillis() - l;
        System.out.println("without try/catch method1 took " + l + " ms, result was " + t.getValue());
    }

    private static void testWithTryCatch(Test t) {
        t.reset();
        long l = System.currentTimeMillis();
        for (int j = 0; j < 10; j++)
            for (int i = 1; i <= 100000000; i++)
                try {
                    t.method1(i);
                } catch (Exception ignored) {
                }

        l = System.currentTimeMillis() - l;
        System.out.println("with try/catch method1 took " + l + " ms, result was " + t.getValue());
    }
}

prints

with try/catch method1 took 9723 ms, result was 2
without try/catch method1 took 9456 ms, result was 2
with try/catch method1 took 9672 ms, result was 2
without try/catch method1 took 9476 ms, result was 2
with try/catch method1 took 8375 ms, result was 2
without try/catch method1 took 8233 ms, result was 2
with try/catch method1 took 8337 ms, result was 2
without try/catch method1 took 8227 ms, result was 2
with try/catch method1 took 8163 ms, result was 2
without try/catch method1 took 8565 ms, result was 2

From these results, it might appear that with try/catch is marginally slower, but not always.

Run on Windows 7, Xeon E5450 with Java 7 update 7.

Problem

I am using the following code to test how slow a try block is. To my surprise, the try block makes it faster. Why? ``` public class Test { int value; public int getValue() { return value; } public void reset() { value = 0; } // Calculates without exception public void method1(int i) { value = ((value + i) / i) << 1; // Will never be true if ((i & 0xFFFFFFF) == 1000000000) { System.out.println("You'll never see this!"); } } public static void main(String[] args) { int i; long l; Test t = new Test(); l = System.currentTimeMillis(); t.reset(); for (i = 1; i < 100000000; i++) { t.method1(i); } l = System.currentTimeMillis() - l; System.out.println("method1 took " + l + " ms, result was " + t.getValue()); // using a try block l = System.currentTimeMillis(); t.reset(); for (i = 1; i < 100000000; i++) { try { t.method1(i); } catch (Exception e) { } } l = System.currentTimeMillis() - l; System.out.println("method1 with try block took " + l + " ms, result was " + t.getValue()); } } ``` My machine is running 64-bit Windows 7 and 64-bit JDK7. I got the following result: ``` method1 took 914 ms, result was 2 method1 with try block took 789 ms, result was 2 ``` And I have run the code many times and every time I got almost the same result. Update: Here is the result of running the test ten times on a MacBook Pro, Java 6. Try-catch makes the method faster, same as on windows. ``` method1 took 895 ms, result was 2 method1 with try block took 783 ms, result was 2 -------------------------------------------------- method1 took 943 ms, result was 2 method1 with try block took 803 ms, result was 2 -------------------------------------------------- method1 took 867 ms, result was 2 method1 with try block took 745 ms, result was 2 -------------------------------------------------- method1 took 856 ms, result was 2 method1 with try block took 744 ms, result was 2 -------------------------------------------------- method1 took 862 ms, result was 2 method1 with try block took 744 ms, result was 2 -------------------------------------------------- method1 took 859 ms, result was 2 method1 with try block took 765 ms, result was 2 -------------------------------------------------- method1 took 937 ms, result was 2 method1 with try block took 767 ms, result was 2 -------------------------------------------------- method1 took 861 ms, result was 2 method1 with try block took 744 ms, result was 2 -------------------------------------------------- method1 took 858 ms, result was 2 method1 with try block took 744 ms, result was 2 -------------------------------------------------- method1 took 858 ms, result was 2 method1 with try block took 749 ms, result was 2 ```

Original source

Related problems