Hate to burst everyone's bubble, but using try/catch
is faster. That's not to say it is the "correct" way, but if performance is key then that's the winner. Here are the results from the following program:
Run 1
- Sub-run 1: Instanceof : 130 ms
- Sub-run 1: Try/catch : 118 ms
- Sub-run 2: Instanceof : 96 ms
- Sub-run 2: Try/catch : 93 ms
- Sub-run 3: Instanceof : 100 ms
- Sub-run 3: Try/catch : 99 ms
Run 2
- Sub-run 1: Instanceof : 140 ms
- Sub-run 1: Try/catch : 111 ms
- Sub-run 2: Instanceof : 92 ms
- Sub-run 2: Try/catch : 92 ms
- Sub-run 3: Instanceof : 105 ms
- Sub-run 3: Try/catch : 95 ms
Run 3
- Sub-run 1: Instanceof : 140 ms
- Sub-run 1: Try/catch : 135 ms
- Sub-run 2: Instanceof : 107 ms
- Sub-run 2: Try/catch : 88 ms
- Sub-run 3: Instanceof : 96 ms
- Sub-run 3: Try/catch : 90 ms
Test environment
- Java: 1.7.0_45
- Mac OSX Mavericks
Discounting warmup sub-runs of each run the instanceof
method only achieves at best the performance of try/catch
. The average (discounting warm-ups) of the instanceof
method is 98 ms and the average of try/catch
is 92 ms.
Please note I did not vary the order in which each method was tested. I always tested a block of instanceof
then a block of try/catch
. I would love to see other results contradicting or confirming these findings.
public class test {
public static void main (String [] args) throws Exception {
long start = 0L;
int who_cares = 0; // Used to prevent compiler optimization
int tests = 100000;
for ( int i = 0; i < 3; ++i ) {
System.out.println("Testing instanceof");
start = System.currentTimeMillis();
testInstanceOf(who_cares, tests);
System.out.println("instanceof completed in "+(System.currentTimeMillis()-start)+" ms "+who_cares);
System.out.println("Testing try/catch");
start = System.currentTimeMillis();
testTryCatch(who_cares, tests);
System.out.println("try/catch completed in "+(System.currentTimeMillis()-start)+" ms"+who_cares);
}
}
private static int testInstanceOf(int who_cares, int tests) {
for ( int i = 0; i < tests; ++i ) {
Exception ex = (new Tester()).getException();
if ( ex instanceof Ex1 ) {
who_cares = 1;
} else if ( ex instanceof Ex2 ) {
who_cares = 2;
}
}
return who_cares;
}
private static int testTryCatch(int who_cares, int tests) {
for ( int i = 0; i < tests; ++i ) {
Exception ex = (new Tester()).getException();
try {
throw ex;
} catch ( Ex1 ex1 ) {
who_cares = 1;
} catch ( Ex2 ex2 ) {
who_cares = 2;
} catch ( Exception e ) {}
}
return who_cares;
}
private static class Ex1 extends Exception {}
private static class Ex2 extends Exception {}
private static java.util.Random rand = new java.util.Random();
private static class Tester {
private Exception ex;
public Tester() {
if ( rand.nextBoolean() ) {
ex = new Ex1();
} else {
ex = new Ex2();
}
}
public Exception getException() {
return ex;
}
}
}