抽象类比Java中的接口更快吗?

Ade*_*lin 2 java jvm

根据这篇文章在这里,在抽象类VS接口,抽象类稍微比接口速度更快,这是什么原因,你可以解释JVM方面使用接口VS抽象类的机制?

4)Java中抽象类和接口之间的第四个区别是抽象类比接口稍快,因为接口在调用Java中的任何重写方法之前都涉及搜索.这在大多数情况下并没有显着差异,但如果您正在编写一个时间关键的应用程序,那么您可能不想遗忘任何一块石头.

Hol*_*ger 10

答案取决于实现细节,但在这种形式中,它是不正确的。事实上,作者已经尝试通过使用“稍微”这个词来逃避事实核查,以接受您从未观察到这种性能差异的可能性。

正如本板所阐述的,这种说法背后的想法是,一个普通类有一个由子类继承的可覆盖方法表(也称为“vtable”),子类可能会在最后添加新方法并替换表条目他们覆盖的方法。因此,第一个解析只需要找到表索引,该索引可以记住,因此后续调用只需要在该索引处调用实际接收器类的方法。

由于接口可能由没有继承关系的不同类实现,因此这些类的实现方法可能位于不同的表索引处。解决这个问题的一种方法是从接口的表到实际类的表进行某种映射。假设这种双重调度会导致调用接口方法比普通方法慢的假设。

但是,像 HotSpot JVM 这样的 JVM 不使用这种双分派。它们像任何其他虚拟方法调用一样针对实际的接收器类解析接口方法调用。只要接收器是同一类层次结构的一部分,比如说,您在Appendable接口上调用一个方法,并且接收器始终是Writer该类的子类,则不需要额外的步骤。对于所有接口方法调用中的大多数,这都能很好地工作。

在某些情况下,接口方法调用将在不相关类的不同实现处结束,例如,当一个方法的调用Appendable有时在StringBuilder和其他时间在结束时Writer,但是,我们有一个无与伦比的场景。这个特殊的调用可能比普通的方法调用稍微慢一点,但是由于不可能用抽象类来构造相同的场景,所以在这里说它比使用抽象类慢是没有意义的。

对于性能相关的代码部分,也称为热点,JVM 将执行运行时优化,这使得这种技术差异无论如何都无关紧要。即使是普通虚方法调用的微小开销通常也会被消除,因为后续优化严重依赖于积极内联目标方法代码的能力,以便能够使用调用者的上下文及其已知的周围条件来优化被调用方的代码。


Hem*_*ngh 5

在Java早期,出现差异的技术原因.你知道"虚拟桌子"或"vtbl"是什么吗?基本上,一个简单的vtbl可以用于直接继承的方法,因此JVM只需要查看两个指针来查找从抽象类继承的方法的代码 - 这相对较快.但是由于任何类都可以实现任意数量的接口,找到实现接口方法的代码将涉及到指向由类实现的接口表的指针,然后在表中搜索以找到用于该接口的实现的vtbl,然后在表中找到方法指针.这显然需要做更多工作,所以调用接口方法的速度要慢得多.

目前,JVM更加智能,大多数此类查找都是在动态编译期间完成的,因此运行时差异很小或根本不存在.