【发布时间】:2018-05-02 14:46:11
【问题描述】:
我正在阅读一些关于 Java 是否可以比 C++ 更快的材料,并看到了以下引用:
Java 可以比 C++ 更快,因为 JIT 可以内联虚函数边界。
Why Java Will Always Be Slower than C++ (wayback link)
这是什么意思?这是否意味着 JIT 可以内联虚函数调用(可能是因为它可以访问运行时信息)而 C++ 必须通过其 vtable 调用该函数?
【问题讨论】:
我正在阅读一些关于 Java 是否可以比 C++ 更快的材料,并看到了以下引用:
Java 可以比 C++ 更快,因为 JIT 可以内联虚函数边界。
Why Java Will Always Be Slower than C++ (wayback link)
这是什么意思?这是否意味着 JIT 可以内联虚函数调用(可能是因为它可以访问运行时信息)而 C++ 必须通过其 vtable 调用该函数?
【问题讨论】:
您的问题的答案是肯定的:这就是引用文本的意思。
JIT 将分析所有加载的类。如果它可以确定在任何给定点只能调用一个可能的方法,它可以避免分派并(如果合适的话)内联方法体。
相比之下,C++ 编译器不知道所有可能的子类型,因此无法确定是否可以对(虚拟)方法进行这种优化。 (当链接器运行时,为时已晚......)
其他答案说您可以在 C++ 中手动进行此优化...但假设您(程序员)可以自己进行分析,并将方法从虚拟更改为非虚拟。但如果你弄错了,你就有一个 bug 需要追查。
顺便说一句,我们可以假设这种优化对于普通的 Java 应用程序是值得的。如果不是,JIT 编译器的人就不会实现它。毕竟,毫无价值的优化只会让 Java 应用程序启动更慢。
【讨论】:
由于将 Java 字节码编译为机器代码被推迟到运行时,JVM 可以执行 profile-guided optimization 和其他需要在代码运行之前不可用的信息的优化。这甚至可能包括“去优化”,即撤销之前进行的优化,以便进行其他优化。
更多信息可以在 Wikipedia 上的 adaptive optimization 下找到,其中包括与内联相关的优化。
【讨论】:
就其价值而言,Java、C++、Assembly 将提供相对相同的性能。
是的,手动优化的 C++、C 或 Asm 可以实现更好的性能......但是,对于大多数应用程序(尝试除严重图形应用程序之外的所有应用程序),这不是瓶颈,而且 -较低的实施成本弥补了任何感知到的较低性能。
【讨论】: