为什么字节码可能比本机代码运行得更快 [已关闭]

2022-09-03 18:31:31

Java很慢。

这不仅仅是一个“都市传说”,它似乎是一个事实。由于延迟,您不会将其用于实时编码,也不会将其用于集群/并行计算。有成千上万的基准测试,特别是“Java vs C#vs C++”。

http://benchmarksgame.alioth.debian.org/

根据上面的网站,不仅Java的性能几乎和C一样好(远非其他的),而且Scala和Clojure(两种在JVM上运行的函数式语言)都比OCaml,Erlang具有更好的性能。

还有很多“Java比X更快”(例如,关于SO的问题:Java运行时性能与本机C / C++代码?)。

因此,在某些情况下,Java似乎很快。有人能解释一下为什么吗?

为什么字节码可能比原生代码运行得更快,在某些情况下,给定动态代码(Scala,Clojure)和垃圾回收?为什么如果它更快,仍然有延迟?

这似乎是一个矛盾,有人可以发光吗?


答案 1

在《编程策划者》一书中,James Gosling解释说:

詹姆斯:没错。如今,我们几乎总是击败真正优秀的C和C++编译器。当您转到动态编译器时,当编译器在最后一刻运行时,您将获得两个优势。一个是你确切地知道你正在运行什么芯片组。很多时候,当人们编译一段C代码时,他们必须编译它以在通用的x86架构上运行。您获得的二进制文件中几乎没有一个特别适合它们中的任何一个。你下载 Mozilla 的最新副本,它几乎可以在任何 Intel 架构 CPU 上运行。几乎只有一个Linux二进制文件。它非常通用,它是用GCC编译的,GCC不是一个很好的C编译器。

当 HotSpot 运行时,它确切地知道您正在运行哪个芯片组。它确切地知道缓存是如何工作的。它确切地知道内存层次结构是如何工作的。它确切地知道所有管道联锁在CPU中的工作方式。它知道这个芯片得到了什么指令集扩展。它可以精确地针对您使用的机器进行优化。然后它的另一半是它实际上看到了应用程序正在运行。它能够有统计数据来知道哪些事情是重要的。它能够内联C编译器永远无法做到的事情。在Java世界中内联的那种东西非常惊人。然后,您可以按照存储管理与现代垃圾回收器一起工作的方式来附加它。使用现代垃圾回收器,存储分配非常快。


答案 2

快速 JVM 使用实时 (JIT) 编译。字节码在运行时动态转换为本机代码。JIT 提供了许多优化机会。有关JIT的更多信息,请参阅此维基百科文章


推荐