Java instanceof在现代JVM实现中是如何实现的?

Java instanceof在现代JVM实现中是如何实现的?,java,jvm,implementation,instanceof,Java,Jvm,Implementation,Instanceof,由于在其他线程中进行了基准测试(参见),Java 6中的instanceof实际上相当快。这是如何实现的 我知道对于单个继承,最快的方法是使用一些嵌套的区间编码,其中每个类保持一个[low,high]区间,instanceof只是一个区间包含测试,即2个整数比较。但它是如何为接口创建的(因为间隔包含仅适用于单个继承)?类加载是如何处理的?加载新的子类意味着需要调整很多时间间隔。AFAIK每个类都知道它扩展的所有类及其实现的接口。这些可以存储在一个哈希集中,给出O(1)个查找时间 当代码经常采用相

由于在其他线程中进行了基准测试(参见),Java 6中的instanceof实际上相当快。这是如何实现的


我知道对于单个继承,最快的方法是使用一些嵌套的区间编码,其中每个类保持一个[low,high]区间,instanceof只是一个区间包含测试,即2个整数比较。但它是如何为接口创建的(因为间隔包含仅适用于单个继承)?类加载是如何处理的?加载新的子类意味着需要调整很多时间间隔。

AFAIK每个类都知道它扩展的所有类及其实现的接口。这些可以存储在一个哈希集中,给出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;
}
如果我把“双打”改成

注意:如果我改变

if (d instanceof Double)


性能是一样的。

我也在考虑这个哈希表方法。但在某些情况下,instanceof似乎比哈希表查找更快。它甚至比没有参数的单个函数调用还要快。生成的代码可以内联。对于上述
Double
的情况,由于该类为
final
,测试与
d!=null&&d.getClass()==Double.class
    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)