據我所知每個類都知道它擴展它實現的類和接口。這些可以存儲在給出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)
的性能是一樣的。
我也在想這個散列表方法。但是在某些情況下,instanceof似乎比散列表查找更快。它比沒有參數的單個函數調用還要快。 – gexicide
生成的代碼可以內聯。對於上面的'Double'的情況,由於類是'final',所以測試與'd!= null && d.getClass()== Double.class'相同 –