楼梯书的摘录:
If efficiency is very important, lean towards using a class. Most Java runtimes make a virtual method invocation of a class member a faster operation than an interface method invocation. Traits get compiled to interfaces and therefore may pay a slight performance overhead. However, you should make this choice only if you know that the trait in question constitutes a performance bottleneck and have evidence that using a class instead actually solves the problem.
我写了一些简单的代码来看看幕后到底发生了什么。我确实注意到了
invokevirtual
在抽象类和 invokeinterface
的情况下使用在接口(interface)的情况下。但无论我写什么类型的代码,它们的表现总是大致相同的。我在服务器模式下使用 HotSpot 1.6.0_18。
是 JIT 在优化方面做得如此出色吗?
有人有示例代码来证明书中关于
invokevirutal
的说法吗?是更快的操作?
最佳答案
如果 HotSpot 注意到调用站点上的所有实例都属于同一类型,则它能够使用单态方法调用,并且虚拟方法和接口(interface)方法都以相同的方式进行优化。文件PerformanceTechniques和 VirtualCalls不区分虚拟方法和接口(interface)方法。
但在一般的非单态情况下,可能会有一些差异。 InterfaceCalls文件说:
There is no simple prefixing scheme in which an interface's methods are displayed at fixed offsets within every class that implements that interface. Instead, in the general (non-monomorphic) case, an assembly-coded stub routine must fetch a list of implemented interfaces from the receiver's klassOop, and walk that list seeking the current target interface.
它还证实了两者的单态情况是相同的:
Nearly the same optimizations apply to interface calls as to virtual calls. As with virtual calls, most interface calls are monomorphic, and can therefore be rendered as direct calls with a cheap check.
其他 JVM 可能有不同的优化。
您可以尝试一个微基准测试 (if you know how),它调用实现相同接口(interface)的多个类以及扩展相同抽象类的多个类的方法。这样应该可以强制 JVM 使用非单态方法调用。 (尽管在现实生活中任何差异都可能无关紧要,因为大多数调用站点无论如何都是单态的。)
关于performance - Scala 中的抽象类真的比特征表现更好吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4962618/