みんなのバブルを破裂させるのは嫌いですが、使用した方try/catch
が速いです。それが「正しい」方法だと言っているわけではありませんが、パフォーマンスが重要な場合は、それが勝者です。以下は、次のプログラムの結果です。
実行 1
- サブラン 1: Instanceof : 130 ミリ秒
- サブラン 1: トライ/キャッチ: 118 ms
- サブラン 2: Instanceof : 96 ミリ秒
- サブラン 2: トライ/キャッチ: 93 ms
- サブラン 3: Instanceof : 100 ミリ秒
- サブラン 3: トライ/キャッチ: 99 ms
実行 2
- サブラン 1: Instanceof : 140 ミリ秒
- サブラン 1: トライ/キャッチ: 111 ms
- サブラン 2: Instanceof : 92 ミリ秒
- サブラン 2: トライ/キャッチ: 92 ms
- サブラン 3: インスタンスオブ : 105 ミリ秒
- サブラン 3: トライ/キャッチ: 95 ms
実行 3
- サブラン 1: Instanceof : 140 ミリ秒
- サブラン 1: トライ/キャッチ: 135 ms
- サブラン 2: Instanceof : 107 ミリ秒
- サブラン 2: トライ/キャッチ: 88 ms
- サブラン 3: Instanceof : 96 ミリ秒
- サブラン 3: トライ/キャッチ: 90 ms
テスト環境
- Java: 1.7.0_45
- Mac OS X マーベリックス
各実行のウォームアップ サブランを割り引くと、このinstanceof
方法ではせいぜい のパフォーマンスしか達成できませんtry/catch
。この方法の平均 (ウォームアップを除く)instanceof
は 98 ミリ秒で、 の平均try/catch
は 92 ミリ秒です。
各メソッドをテストする順序を変えていないことに注意してください。私は常に のブロックをテストし、instanceof
次に のブロックをテストしましたtry/catch
。これらの調査結果と矛盾する、または確認する他の結果が見られることを楽しみにしています。
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;
}
}
}