在我看来,当你编写一个C程序时,编译器知道源和目标平台(缺少一个更好的术语)并且可以优化它正在构建代码的机器。 但在java中,编译器可以做的最好的是对字节码进行优化,这可能很好,但是jvm中仍然有一层必须解释字节码,并且字节码离最终机器架构的转换距离越远,要做好准备就必须做更多的工作。
在我看来,字节码优化器不会那么好,因为它丢失了原始源代码中可用的所有语义信息(可能已经被java编译器的优化器宰了。)
所以甚至可以用java编译器来达到C的效率吗?
答案 0 :(得分:5)
实际上,字节码JIT编译器在许多情况下超过静态编译语言的性能,因为它可以实时和实际执行上下文中评估字节代码。因此,应用程序性能会随着它继续运行而增加。
答案 1 :(得分:4)
凯文说。此外,字节码优化器(JIT)还可以利用运行时信息来执行更好的优化。例如,它知道什么代码执行更多(热点),因此它不会花时间优化很少执行的代码。它可以完成配置文件引导优化为您提供的大部分内容(分支预测等),但无论目标处理器是什么,它都可以实时运行。这就是JVM在达到最佳性能之前通常需要“预热”的原因。
答案 2 :(得分:3)
理论上,两个优化器应该“相同”,因为c / c ++编译器的标准做法是对生成的程序集执行优化而不是源代码,因此您已经丢失了任何语义信息。
答案 3 :(得分:2)
如果您读取字节代码,您可能会发现编译器没有很好地优化代码。但是,JIT可以优化代码,所以这无关紧要。
假设您在x86机器上编译代码并且出现了新的体系结构,我们称之为x64,相同的Java二进制文件可以利用该体系结构的新功能,即使在编译代码时它可能不存在。这意味着您可以使用旧的库分发并利用最新的硬件特定优化。你不能用C / C ++来做到这一点。
Java可以优化虚拟方法的内联调用。假设您有一个具有许多不同可能实现的虚方法。但是,实际上大部分时间都会调用一两个实现。 JIT可以检测到这个并内联最多两个方法实现,但如果碰巧调用另一个实现,它仍然可以正常运行。你不能用C / C ++
做到这一点Java 7支持锁定/同步对象的转义分析,它可以检测到对象仅在本地上下文中使用并删除该对象的同步。 在当前版本的Java中,它可以检测两个连续方法是否锁定同一个对象并保持它们之间的锁定(而不是释放并重新获取锁定) 你不能用C / C ++做到这一点,因为没有语言级别的锁定理解。