私の知る限り、各クラスは、それが拡張するすべてのクラスとそれが実装するインターフェースを知っています。これらは、O(1) ルックアップ時間を提供するハッシュ セットに格納できます。
コードが頻繁に同じ分岐を取る場合、分岐を取るべきかどうかを判断する前に CPU が分岐内のコードを実行できるため、ほとんどコストを削減できます。
マイクロ ベンチマークは 4 年前に実行されたので、最新の CPU と JVM ははるかに高速であると期待しています。
public static void main(String... args) {
Object[] doubles = new Object[100000];
Arrays.fill(doubles, 0.0);
doubles[100] = null;
doubles[1000] = null;
for (int i = 0; i < 6; i++) {
testSameClass(doubles);
testSuperClass(doubles);
testInterface(doubles);
}
}
private static int testSameClass(Object[] doubles) {
long start = System.nanoTime();
int count = 0;
for (Object d : doubles) {
if (d instanceof Double)
count++;
}
long time = System.nanoTime() - start;
System.out.printf("instanceof Double took an average of %.1f ns%n", 1.0 * time / doubles.length);
return count;
}
private static int testSuperClass(Object[] doubles) {
long start = System.nanoTime();
int count = 0;
for (Object d : doubles) {
if (d instanceof Number)
count++;
}
long time = System.nanoTime() - start;
System.out.printf("instanceof Number took an average of %.1f ns%n", 1.0 * time / doubles.length);
return count;
}
private static int testInterface(Object[] doubles) {
long start = System.nanoTime();
int count = 0;
for (Object d : doubles) {
if (d instanceof Serializable)
count++;
}
long time = System.nanoTime() - start;
System.out.printf("instanceof Serializable took an average of %.1f ns%n", 1.0 * time / doubles.length);
return count;
}
最終的に印刷
instanceof Double took an average of 1.3 ns
instanceof Number took an average of 1.3 ns
instanceof Serializable took an average of 1.3 ns
「ダブル」を変更すると
for(int i=0;i<doubles.length;i+=2)
doubles[i] = "";
私は得る
instanceof Double took an average of 1.3 ns
instanceof Number took an average of 1.6 ns
instanceof Serializable took an average of 2.2 ns
注:私が変更した場合
if (d instanceof Double)
に
if (d != null && d.getClass() == Double.class)
性能は同じでした。