刚刚在维基百科中偶然发现了这一点:
由于 C++ 额外的虚拟表查找,Java 访问派生实例方法的速度比 C++ 访问派生虚拟方法的速度要快。但是,C++ 中的非虚拟方法不受 V-Table 性能瓶颈的影响,因此表现出与 Java 相似的性能。
它是否正确?据我所知,Java 中的所有调用都是虚拟的,并且仍然依赖于虚拟表,因此我的常见逻辑表明 Java 调用不可能比虚拟 C++ 调用更快。
是我被误导了还是文章有误?无论如何-在运行时解决调用是否有比虚拟表更快的方法?
刚刚在维基百科中偶然发现了这一点:
由于 C++ 额外的虚拟表查找,Java 访问派生实例方法的速度比 C++ 访问派生虚拟方法的速度要快。但是,C++ 中的非虚拟方法不受 V-Table 性能瓶颈的影响,因此表现出与 Java 相似的性能。
它是否正确?据我所知,Java 中的所有调用都是虚拟的,并且仍然依赖于虚拟表,因此我的常见逻辑表明 Java 调用不可能比虚拟 C++ 调用更快。
是我被误导了还是文章有误?无论如何-在运行时解决调用是否有比虚拟表更快的方法?
它可能与 JIT 编译执行的优化有关。在某些情况下,我可以想象 JVM 检测到某个(虚拟)调用总是引用某个实现并且不需要查找。
OTOH,C++ 编译器也可能能够推断出在某些情况下不需要查找并产生同样好的代码。此外,C++ 不需要虚函数,因此存在 Java 不提供的替代方法。
也就是说,如果您需要virtual
C++ 中提供的功能,那么我通常没有更好的选择。如果您关心性能,请注意virtual
通常确实有成本,并且只应在需要时使用它。
总的来说,我发现像你引用的那样的陈述没有帮助和误导(当然不是你的错)。
阅读该报价的来源:
因为编译器知道实际加载和调用了哪些类,所以它知道哪些方法可以去虚拟化和内联。(值得注意的是,现代 java 编译器也知道如何在 JIT 编译发生后加载覆盖方法的情况下“反编译”内联调用。)
虽然我不明白为什么 C++ 编译器不能做到这一点。