我意识到字节码与本机代码(可移植性)的好处。
但是假设您总是知道您的代码将在 x86 架构上运行,那么为什么不针对 x86 进行编译并获得性能优势呢?
请注意,我假设本机代码编译有性能提升。有些人回答说实际上可能没有收益,这对我来说是新闻。
“Solaris”是一个操作系统,而不是 CPU 架构。安装在实际机器上的 JVM 将编译为本机 CPU 指令。Solaris 可以是 SPARC、x86 或 x86-64 体系结构。
此外,JIT 编译器可以根据您拥有的实际 CPU 系列进行特定于处理器的优化。例如,不同的指令序列在 Intel CPU 上比在 AMD CPU 上更快,并且针对您的确切平台的 JIT 编译器可以利用这些信息来生成高度优化的代码。
字节码在为(例如)Solaris 编译的 Java 虚拟机中运行。它将针对该操作系统进行优化。
在现实世界的情况下,您经常会看到 Java 代码在运行时具有相同或更好的性能,这得益于在虚拟机代码上构建内存管理之类的东西——这些代码将经过多年的发展和成熟。
为 JVM 构建的好处不仅仅是可移植性 - 例如,每次发布新的 JVM 时,您编译的字节码都会获得来自行业最佳的任何优化、算法改进等。另一方面,一旦你编译了你的 C 代码,就是这样。
因为使用即时编译,性能优势微乎其微。
实际上,JIT 实际上可以更快地完成许多事情。
在运行之后,它已经被 JIT 编译成 Solaris 原生代码。如果您在上传到目标站点之前编译它,您将无法获得任何其他好处。
您可能会或可能不会获得性能优势。但是您更有可能会受到性能损失:静态编译无法进行 JIT 优化,因此性能只能与编译器使其“蒙住眼睛”一样好(无需实际分析程序并相应地对其进行优化,这就是JIT 编译器(例如 HotSpot)。
直观上令人惊讶的是,编译是多么便宜(资源方面),并且仅通过观察正在运行的程序就可以自动优化多少。黑魔法,但对我们有好处:-)
顺便说一句,所有这些关于 JIT 的讨论都已经过时了大约七年。现在涉及的技术称为 HotSpot,它不仅仅是 JIT。
“为什么不为 x86 编译”
因为那样你就不能利用它运行的特定 cpu 的特定功能。特别是,如果我们将“为 x86 编译”理解为“生成可以在 386 及其后代上运行的本机代码”,那么生成的代码甚至不能依赖像 mmx 指令这样古老的东西。
因此,最终结果是您需要针对将要运行的每个确切架构进行编译(那些尚不存在的架构呢),并让安装程序选择要放置的可执行文件。或者,我听说英特尔 C++ 编译器会生成相同函数的多个版本,仅在使用的 cpu 功能上有所不同,并在运行时根据 CPU 报告的可用内容选择正确的版本。
另一方面,您可以将字节码视为“半编译”源,类似于本机编译器(除非被要求)实际上不会写入磁盘的中间格式。然后运行时环境可以进行最终编译,确切地知道将使用什么架构。这就是为什么一些 C#/.net 代码在不久前的一些基准测试中在一些 cpu 密集型任务上的性能略优于 c++ 代码的给定原因。
字节码的“最终编译”还可以做出额外的优化假设,这些假设(从静态编译的角度来看)明显不安全*,如果以后发现这些假设错误,只需重新编译。
我猜是因为 JIT(及时)编译非常先进。