现代 JVM 实现中,instanceof 是如何实现的?

2023-12-02

由于在其他线程中完成的基准测试(参见https://stackoverflow.com/a/397617/1408611)结果表明,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;
}

最后打印

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] = "";

I get

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)

to

if (d != null && d.getClass() == Double.class)

表现是一样的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

现代 JVM 实现中,instanceof 是如何实现的? 的相关文章

随机推荐

  • 如何使用 Joda Time 检查 DateTime 是否发生重复事件?

    I ve a DateTime代表重复事件的开始 ADays 每日周期 将代表循环周期 我认为这种反复发生的事件永远不会停止 from 2013 06 27 period 3 days nextOccurence will be 2013
  • 如何使用Python使用Bulk API将关键字存储在ES中

    我必须在与我的 python 程序集成的 ElasticSearch 中存储一些消息 现在我尝试存储的消息是 d message this is message for index nr in range 1 5 ElasticSearch
  • 使用 JPanel 列表制作表格

    我需要 Java 应用程序中的一个表 首先我习惯了类的对象JTable但我的桌子有很多功能 现在我尝试使用一系列功能JPanel组件而不是表格 如何制作包含面板列表的表格 如果您需要创建一个由以下内容组成的表JPanel含有JTextAre
  • Azure 搜索建议中存在不同的值?

    我正在将关系数据库上的搜索功能卸载到 Azure 搜索 我的产品表包含序列号 零件号等列 可以有多个具有相同零件号的序列号 我想创建一个可以自动完成零件编号的建议 但在我的场景中 我在建议中收到了很多重复项 因为在多个条目中找到了partN
  • Linux 排序命令的异常行为

    在 Linux shell 上的结果echo e arrays2 2 narrays 2 narrays3 2 sort is arrays 2 arrays2 2 arrays3 2 和结果echo e arrays2 28 narray
  • 如何为“两个”单词编写别名[重复]

    这个问题在这里已经有答案了 别名的标准用法是为扩展命令编写快捷方式 例如 alias ls ls color 我想知道是否可以在左侧添加 参数 以便以相反的方式工作 使用上面的例子 我有兴趣知道是否alias ls color ls 是可能
  • 在Android中使用aChartEngine组合两个条形图和两个折线图

    下面的代码组合了两个条形图和两个折线图 public class GraphCombination private Context context private String weekDays new String Sunday Mond
  • 在 Django 模型中设置主键起始值

    我正在准备一个模型如下 class SomeModel models Model id models BigIntegerField primary key True null False unique True 但我的主键必须是有效的 9
  • C# 已建立的连接被主机中的软件中止

    这些错误在我的游戏服务器上变得越来越频繁 它们导致服务器不断关闭并重新启动 System Net Sockets SocketException 0x80004005 An established connection was aborte
  • 对 STL 字符串使用 fread/fwrite。这是对的吗?

    我有一个包含字符串的结构 像这样的东西 struct Chunk int a string b int c 因此 我想我无法使用 fread 和 fwrite 函数从文件中写入和读取此结构 因为字符串可能保留不同的内存容量 但这样的代码可以
  • 编辑音频/重新录制文件的一部分

    我希望用户能够在应用程序中录制音频 然后能够选择文件的一部分并重新录制 例如 也许他们最初录制 现在怎么样 棕色母牛 然后选择该结尾并重新录制 皱眉母猪 这将被合并到初始文件中 该文件将是 现在怎么样 皱眉母猪 这似乎比我想象的要困难得多
  • 应用程序网关 - 502 错误

    我已经按照 MS 文档设置了一个新的应用程序网关 我已经配置了后端池 它通过 FQDN 连接到应用程序服务 不知何故 每次浏览应用程序网关时 我都会立即收到 502 直接浏览网站没有任何问题 我已经解决了这个问题 这是解决方案 如果您的后端
  • 如何从 Java 读取 Oracle 数据库中的 CLOB 列

    我在数据库中有一个表 其中列的数据类型 STATUS 是 CLOB 我需要读取该 STATUS create table STATUS TABLE STATE ID number 20 0 STATUS clob 我正在尝试阅读如下 CLO
  • 在类层次结构中混合 Java 1.4 和 1.6 字节码

    先问问题 故事如下 在类层次结构中混合不同的字节码版本是否安全 有哪些风险 对于一种情况 C类扩展B B类扩展A类 A类实现接口I 我的问题将涉及以下示例场景 A 类编译为 Java 1 6 字节码 并具有 1 6 特性 如泛型等 继承人
  • 使用 Python + Selenium 选择 iframe

    所以 我对如何在 Selenium 中做到这一点感到非常困惑 并且在任何地方都找不到答案 所以我分享我的经验 我试图选择一个 iframe 但没有运气 或者无论如何都不能重复 HTML 是
  • 使用expressjs发布到远程URL

    我的 server js 中有这个 app post leadAPI ed function request response api post code here 在此发布请求中 我需要将请求正文中包含的数据发布到具有特定 URL 的外部
  • 在 Python 3 .4 中连接字符串和 int [重复]

    这个问题在这里已经有答案了 我是 Python 新手 所以我一直在进行自己的一组练习 以简单地开始记住基本函数和语法 我正在使用PyCharmIDE 和 Python 3 4 我在进行一些基本的字符串和整数连接练习时遇到了问题 下面的每个实
  • 动态创建/绘制图像以放入 Android 视图中

    我不确定我是否以 正确 的方式这样做 所以我也对其他选择持开放态度 这就是我想要实现的目标 我想要一个包含图表的视图 该图表应该由应用程序本身动态创建 图表应该是可缩放的 并且一开始可能会比屏幕大 800x600 左右 我打算从简单的开始
  • 如何在java中读取Doc或Docx文件? [关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 我想用java读取word文件 import org apache poi poifs
  • 现代 JVM 实现中,instanceof 是如何实现的?

    由于在其他线程中完成的基准测试 参见https stackoverflow com a 397617 1408611 结果表明 Java 6 中的 instanceof 实际上相当快 这是如何实现的 我知道 对于单继承 最快的想法是进行一些