问题 Java如何内联虚拟功能边界?


我正在阅读一些关于Java是否比C ++更快的材料,并且看到了以下引用:

Java可以比C ++更快,因为JIT可以内联虚拟功能边界。

为什么Java总是比C ++慢 (回来链接

这是什么意思?这是否意味着JIT可以内联虚函数调用(因为可能它可以访问运行时信息)而C ++必须通过其vtable调用函数?


9214
2017-11-12 02:51


起源



答案:


您的问题的答案是肯定的:这就是引用文本的含义。

JIT将分析所有已加载的类。如果它可以确定在任何给定点只能调用一种可能的方法,则可以避免调度和(如果适用)内联方法体。

相比之下,C ++编译器不知道所有可能的子类型,因此无法确定是否可以对(虚拟)方法执行此优化。 (当链接器运行时,为时已晚......)

其他答案说你可以在C ++中手动进行优化......但是假设你(程序员)可以自己做分析,并将方法从虚拟变为非虚拟。但如果你弄错了,你就有一个要追查的错误。

顺便说一句,我们可以假设这种优化  值得一般的Java应用程序。如果不是,JIT编译器人员就不会实现它。毕竟,一个毫无价值的优化只会让Java应用程序启动得更慢。


10
2017-11-12 03:38



+1回答实际问题 - ykaganovich
一个好处是可以内联getter和setter意味着完全的抽象保护(编码到接口和所有),而不是每次都自动支付罚款。 - Thorbjørn Ravn Andersen


答案:


您的问题的答案是肯定的:这就是引用文本的含义。

JIT将分析所有已加载的类。如果它可以确定在任何给定点只能调用一种可能的方法,则可以避免调度和(如果适用)内联方法体。

相比之下,C ++编译器不知道所有可能的子类型,因此无法确定是否可以对(虚拟)方法执行此优化。 (当链接器运行时,为时已晚......)

其他答案说你可以在C ++中手动进行优化......但是假设你(程序员)可以自己做分析,并将方法从虚拟变为非虚拟。但如果你弄错了,你就有一个要追查的错误。

顺便说一句,我们可以假设这种优化  值得一般的Java应用程序。如果不是,JIT编译器人员就不会实现它。毕竟,一个毫无价值的优化只会让Java应用程序启动得更慢。


10
2017-11-12 03:38



+1回答实际问题 - ykaganovich
一个好处是可以内联getter和setter意味着完全的抽象保护(编码到接口和所有),而不是每次都自动支付罚款。 - Thorbjørn Ravn Andersen


由于将Java字节码编译成机器代码会延迟到运行时,因此JVM可以执行 配置文件引导优化 以及其他需要在代码运行之前无法获得信息的优化。这甚至可能包括“去优化”,其中先前进行的优化被撤销,以便可以进行其他优化。

有关这方面的更多信息,请参阅 自适应优化 在维基百科上,其中包括与内联相关的优化。


4
2017-11-12 03:05



我知道存在可以使用配置文件信息来确定是否进行这些优化的C ++编译器。 C ++的真正问题在于标准链接模型意味着调用者和被调用者不一定被编译在一起。 - Tom Hawtin - tackline
是的,新的gcc可以进行这种链接时优化(LTO)。 - Adam Goode


对于它的价值,Java,C ++,Assembly将提供相对相同的性能。

是的,可以通过手动优化的C ++,C或Asm实现更好的性能......然而,对于那些应用程序的大量应用(尝试除了严肃的图形应用程序之外的所有东西),这不是瓶颈,而且 - 和 - 的成本更低实施弥补了任何感知到的较低性能。


2
2017-11-12 02:57