根据本文的这里,在抽象类和接口上,抽象类略快于接口。为什么,你能用JVM来解释使用接口和抽象类的机制吗?
发布于 2018-07-02 08:37:25
答案取决于实现细节,但在这种形式下,它是不正确的。事实上,作者已经尝试通过使用“稍微”一词来回避事实-检查,以便让你永远不会观察到这样的性能差异。
正如在这个板中阐述的那样,这种语句背后的思想是,普通类有一个由子类继承的可重写方法表(也称为“vtable”),子类可以在最后添加新方法,并为它们覆盖的方法替换表条目。因此,第一个解析只需要找到可以记住的表索引,因此后续调用只需要在该索引处调用实际接收方类的方法。
由于接口可以由不具有继承关系的不同类实现,因此实现方法可能位于这些类的不同表索引处。解决这一问题的一种方法是从接口的表到实际的类表进行某种映射。假设这种双重调度导致了调用接口方法比普通方法慢的假设。
但是,像HotSpot JVM这样的JVM不使用这种双重调度。它们像任何其他虚拟方法调用一样,针对实际的接收方类解析接口方法调用。只要接收器是同一类层次结构的一部分,例如,您在Appendable接口上调用一个方法,并且接收方始终是Writer类的子类,则不需要额外的步骤。对于大多数的接口方法调用,这是相当好的工作。
在有些情况下,接口方法调用将在不相关类的不同实现中结束,例如,当对Appendable方法的调用有时在StringBuilder而其他时候在Writer结束时,但是,我们有一个无法比拟的场景。这种特定的调用可能比普通的方法调用稍微慢一些,但是由于不可能用抽象类构造相同的场景,所以说它比在这里使用抽象类慢是没有任何意义的。
对于性能相关的代码部分(也称为热点),JVM将执行运行时优化,这将使这种技术差异变得无关紧要。即使是普通虚拟方法调用的微小开销通常也会被消除,因为随后的优化严重依赖于积极内联目标方法的代码的能力,从而能够使用调用方的上下文及其已知的周围条件来优化被调用方的代码。
发布于 2022-04-28 07:28:53
https://stackoverflow.com/questions/51112973
复制相似问题