如何在现代JVM实现中实现instanceof? [英] How is instanceof implemented in modern JVM implementations?

查看:141
本文介绍了如何在现代JVM实现中实现instanceof?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于在其他线程中完成了基准测试(参见 https://stackoverflow.com/a/397617/1408611)显示Java 6中的instanceof实际上非常快。这是如何实现的?

Due to the benchmarking done in other threads (cf. https://stackoverflow.com/a/397617/1408611) it was shown that instanceof in Java 6 is actually quite fast. How is this achieved?

我知道对于单继承,最快的想法是使用一些嵌套间隔编码,其中每个类保持[低,高]间隔和一个实例只是一个区间包含测试,即2个整数比较。但它是如何制作接口的(因为区间包含仅适用于单继承)?如何处理类加载?加载新的子类意味着必须调整很多区间。

I know that for single inheritance, the fastest idea is having some nested interval encoding where each class maintains a [low,high] interval and an instanceof is simply an interval inclusion test, i.e. 2 integer comparisons. But how is it made for interfaces (as interval inclusion only works for single inheritance)? And how is class loading handled? Loading new subclasses means that a lot of intervals have to be adjusted.

推荐答案

AFAIK每个类都知道它扩展的所有类和接口它实现了。这些可以存储在散列集中,给出O(1)查找时间。

AFAIK each class knows all the classes it extends and interfaces it implements. These could be stored in a hash set giving O(1) lookup time.

当代码经常采用相同的分支时,由于CPU可以执行,因此几乎可以消除成本分支中的代码在确定是否应该让分支成本接近于零之前。

When code often takes the same branch, the cost can be almost eliminated as the CPU can execute the code in the branch before it has determined whether it should take the branch making the cost next to nothing.

由于4年前进行了微基准测试,我预计最新的CPU和JVM要快得多。

As the micro-benchmark was performed 4 years ago, I expect the latest CPUs and JVMs to be much faster.

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)

表现相同。

这篇关于如何在现代JVM实现中实现instanceof?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆