当前位置: 首页 > 面试题库 >

为什么接口方法调用比具体调用慢?

晋承嗣
2023-03-14
问题内容

当我发现抽象类和接口之间的区别时,这个问题就浮现在脑海中。在这篇文章中,我知道接口很慢,因为它们需要额外的间接访问。但是我没有得到接口而不是抽象类或具体类所需的间接类型,请对此进行澄清。提前致谢


问题答案:

关于性能的神话很多,有些可能在几年前是正确的,而在没有JIT的VM上可能仍然正确。

Android文档(请记住,Android没有JVM,而是Dalvik
VM)曾经说过,在接口上调用方法要比在类上调用方法慢,因此它们有助于传播神话(这也是可能的)在Dalvik
VM上打开JIT之前,速度较慢)。该文档现在会说:

表现神话

本文档的先前版本提出了各种误导性主张。我们在这里解决其中一些问题。

在没有JIT的设备上,通过具有确切类型的变量而不是接口来调用方法的效率确实更高。(因此,例如,即使在两种情况下,地图都是HashMap,在HashMap地图上调用方法也比Map地图便宜。)事实并非如此,它慢了2倍;实际差异要慢6%。此外,JIT使两者实际上无法区分。

资料来源:为Android上的性能而设计

对于JVM中的JIT可能同样如此,否则会很奇怪。



 类似资料:
  • 接口具有抽象方法和非抽象方法。我想使用super并在具体类中重写。我的问题是为什么我必须这样调用Calculator.super.ramdom()?为什么不工作?

  • 问题内容: 假设我有以下代码: 当我调用fmt.Println(myCar)且有问题的对象是指针时,我的String()方法将被正确调用。如果该对象是一个值,则使用Go内置的默认格式对我的输出进行格式化,而不会调用用于格式化该对象的代码。 有趣的是,无论哪种情况,如果我手动调用myCar.String(),无论我的对象是指针还是值,它都能正常工作。 与Println一起使用时,无论对象是基于值还是

  • 下面是我试图做的一个非常简单的说明: 最后一个方法调用(consumer.consumer())给了我一个编译器错误 Out projected type’EventConsumer 我知道Kotlin对泛型的要求比Java严格得多,这可能就是它不起作用的原因,但我该如何正确地实现这样的东西呢?

  • 这是另一个非常经典的 java 多线程面试问题,而且在面试中会经常被问到。很简单,但是很多人都会答不上来! new 一个 Thread,线程进入了新建状态。调用 start() 方法,会启动一个线程并使线程进入了就绪状态,当分配到时间片后就可以开始运行了。 start() 会执行线程的相应准备工作,然后自动执行 run() 方法的内容,这是真正的多线程工作。 而直接执行 run() 方法,会把 r

  • 4.2 接口调用 Camel管理端定义了两个版本的接口。第一版接口路径以"/api/"开头,第二版接口路径以"/api/v2"开头。 两个版本接口的主要区别在于:第二版本接口将更改配置、发布配置文件这两部操作聚合成为一个原子操作。则调用第二版本接口,如果成功,则Nginx当前配置为更改之后的配置;如果失败,则Nginx当前配置为调用接口之前的配置。不会出现不安全的中间状态。 第一版本接口: 更新节

  • 我有一个扩展了B类的a类。 A是这样定义的,它也覆盖了B的方法: B是这样定义的: 因此,如果我初始化A的一个对象,构造函数将调用调用方法doSomething()的超类之一。但哪一个会被处决?B的实现还是A中被重写的实现?