Should try...catch go inside or outside a loop? Should try...catch go inside or outside a loop? java java

Should try...catch go inside or outside a loop?


PERFORMANCE:

There is absolutely no performance difference in where the try/catch structures are placed. Internally, they are implemented as a code-range table in a structure that is created when the method is called. While the method is executing, the try/catch structures are completely out of the picture unless a throw occurs, then the location of the error is compared against the table.

Here's a reference: http://www.javaworld.com/javaworld/jw-01-1997/jw-01-hood.html

The table is described about half-way down.


Performance: as Jeffrey said in his reply, in Java it doesn't make much difference.

Generally, for readability of the code, your choice of where to catch the exception depends upon whether you want the loop to keep processing or not.

In your example you returned upon catching an exception. In that case, I'd put the try/catch around the loop. If you simply want to catch a bad value but carry on processing, put it inside.

The third way: You could always write your own static ParseFloat method and have the exception handling dealt with in that method rather than your loop. Making the exception handling isolated to the loop itself!

class Parsing{    public static Float MyParseFloat(string inputValue)    {        try        {            return Float.parseFloat(inputValue);        }        catch ( NumberFormatException e )        {            return null;        }    }    // ....  your code    for(int i = 0; i < max; i++)     {        String myString = ...;        Float myNum = Parsing.MyParseFloat(myString);        if ( myNum == null ) return;        myFloats[i] = (float) myNum;    }}


All right, after Jeffrey L Whitledge said that there was no performance difference (as of 1997), I went and tested it. I ran this small benchmark:

public class Main {    private static final int NUM_TESTS = 100;    private static int ITERATIONS = 1000000;    // time counters    private static long inTime = 0L;    private static long aroundTime = 0L;    public static void main(String[] args) {        for (int i = 0; i < NUM_TESTS; i++) {            test();            ITERATIONS += 1; // so the tests don't always return the same number        }        System.out.println("Inside loop: " + (inTime/1000000.0) + " ms.");        System.out.println("Around loop: " + (aroundTime/1000000.0) + " ms.");    }    public static void test() {        aroundTime += testAround();        inTime += testIn();    }    public static long testIn() {        long start = System.nanoTime();        Integer i = tryInLoop();        long ret = System.nanoTime() - start;        System.out.println(i); // don't optimize it away        return ret;    }    public static long testAround() {        long start = System.nanoTime();        Integer i = tryAroundLoop();        long ret = System.nanoTime() - start;        System.out.println(i); // don't optimize it away        return ret;    }    public static Integer tryInLoop() {        int count = 0;        for (int i = 0; i < ITERATIONS; i++) {            try {                count = Integer.parseInt(Integer.toString(count)) + 1;            } catch (NumberFormatException ex) {                return null;            }        }        return count;    }    public static Integer tryAroundLoop() {        int count = 0;        try {            for (int i = 0; i < ITERATIONS; i++) {                count = Integer.parseInt(Integer.toString(count)) + 1;            }            return count;        } catch (NumberFormatException ex) {            return null;        }    }}

I checked the resulting bytecode using javap to make sure that nothing got inlined.

The results showed that, assuming insignificant JIT optimizations, Jeffrey is correct; there is absolutely no performance difference on Java 6, Sun client VM (I did not have access to other versions). The total time difference is on the order of a few milliseconds over the entire test.

Therefore, the only consideration is what looks cleanest. I find that the second way is ugly, so I will stick to either the first way or Ray Hayes's way.