试图回答这张票:instanceof 和 Class.isAssignableFrom(...) 有什么区别?
我做了一个性能测试:
class A{}
class B extends A{}
A b = new B();
void execute(){
boolean test = A.class.isAssignableFrom(b.getClass());
// boolean test = A.class.isInstance(b);
// boolean test = b instanceof A;
}
@Test
public void testPerf() {
// Warmup the code
for (int i = 0; i < 100; ++i)
execute();
// Time it
int count = 100000;
final long start = System.nanoTime();
for(int i=0; i<count; i++){
execute();
}
final long elapsed = System.nanoTime() - start;
System.out.println(count+" iterations took " + TimeUnit.NANOSECONDS.toMillis(elapsed) + "ms.);
}
这给了我:
- A.class.isAssignableFrom(b.getClass()) : 100000 次迭代耗时15 毫秒
- A.class.isInstance(b) : 100000 次迭代耗时12ms
- b instanceof A : 100000 次迭代耗时6ms
但是玩迭代次数,我可以看到性能是恒定的。对于 Integer.MAX_VALUE :
- A.class.isAssignableFrom(b.getClass()) : 2147483647 次迭代耗时15 毫秒
- A.class.isInstance(b) : 2147483647 次迭代耗时12ms
- b instanceof A : 2147483647 次迭代耗时6ms
认为这是一个编译器优化(我用 JUnit 运行了这个测试),我把它改成了:
@Test
public void testPerf() {
boolean test = false;
// Warmup the code
for (int i = 0; i < 100; ++i)
test |= b instanceof A;
// Time it
int count = Integer.MAX_VALUE;
final long start = System.nanoTime();
for(int i=0; i<count; i++){
test |= b instanceof A;
}
final long elapsed = System.nanoTime() - start;
System.out.println(count+" iterations took " + TimeUnit.NANOSECONDS.toMillis(elapsed) + "ms. AVG= " + TimeUnit.NANOSECONDS.toMillis(elapsed/count));
System.out.println(test);
}
但性能仍然与迭代次数“无关”。有人可以解释这种行为吗?