15

我意识到字节码与本机代码(可移植性)的好处

但是假设您总是知道您的代码将在 x86 架构上运行,那么为什么不针对 x86 进行编译并获得性能优势呢?

请注意,我假设本机代码编译有性能提升。有些人回答说实际上可能没有收益,这对我来说是新闻。

4

9 回答 9

15

因为性能提升(如果有的话)不值得麻烦。

此外,垃圾收集对性能非常重要。JVM 的 GC 可能比嵌入在已编译可执行文件中的 GC 更好,比如GCJ

即时编译甚至可以带来更好的性能,因为与编译时的编译器相比,JIT 有更多的运行时信息可用于优化编译。请参阅JIT上的维基百科页面。

于 2010-02-27T20:27:52.673 回答
11

“Solaris”是一个操作系统,而不是 CPU 架构。安装在实际机器上的 JVM 将编译为本机 CPU 指令。Solaris 可以是 SPARC、x86 或 x86-64 体系结构。

此外,JIT 编译器可以根据您拥有的实际 CPU 系列进行特定于处理器的优化。例如,不同的指令序列在 Intel CPU 上比在 AMD CPU 上更快,并且针对您的确切平台的 JIT 编译器可以利用这些信息来生成高度优化的代码。

于 2010-02-27T20:28:49.140 回答
7

字节码在为(例如)Solaris 编译的 Java 虚拟机中运行它将针对该操作系统进行优化。

在现实世界的情况下,您经常会看到 Java 代码在运行时具有相同或更好的性能,这得益于在虚拟机代码上构建内存管理之类的东西——这些代码将经过多年的发展和成熟。

为 JVM 构建的好处不仅仅是可移植性 - 例如,每次发布新的 JVM 时,您编译的字节码都会获得来自行业最佳的任何优化、算法改进等。另一方面,一旦你编译了你的 C 代码,就是这样。

于 2010-02-27T20:25:00.130 回答
5

因为使用即时编译,性能优势微乎其微。

实际上,JIT 实际上可以更快地完成许多事情。

于 2010-02-27T20:25:24.223 回答
4

在运行之后,它已经被 JIT 编译成 Solaris 原生代码。如果您在上传到目标站点之前编译它,您将无法获得任何其他好处。

于 2010-02-27T20:27:01.037 回答
4

您可能会或可能不会获得性能优势。但是您更有可能会受到性能损失:静态编译无法进行 JIT 优化,因此性能只能与编译器使其“蒙住眼睛”一样好(无需实际分析程序并相应地对其进行优化,这就是JIT 编译器(例如 HotSpot)。

直观上令人惊讶的是,编译是多么便宜(资源方面),并且仅通过观察正在运行的程序就可以自动优化多少。黑魔法,但对我们有好处:-)

于 2010-02-27T20:29:43.227 回答
1

顺便说一句,所有这些关于 JIT 的讨论都已经过时了大约七年。现在涉及的技术称为 HotSpot,它不仅仅是 JIT。

于 2010-02-28T06:20:38.273 回答
1

“为什么不为 x86 编译”

因为那样你就不能利用它运行的特定 cpu 的特定功能。特别是,如果我们将“为 x86 编译”理解为“生成可以在 386 及其后代上运行的本机代码”,那么生成的代码甚至不能依赖像 mmx 指令这样古老的东西。

因此,最终结果是您需要针对将要运行的每个确切架构进行编译(那些尚不存在的架构呢),并让安装程序选择要放置的可执行文件。或者,我听说英特尔 C++ 编译器会生成相同函数的多个版本,仅在使用的 cpu 功能上有所不同,并在运行时根据 CPU 报告的可用内容选择正确的版本。

另一方面,您可以将字节码视为“半编译”源,类似于本机编译器(除非被要求)实际上不会写入磁盘的中间格式。然后运行时环境可以进行最终编译,确切地知道将使用什么架构。这就是为什么一些 C#/.net 代码在不久前的一些基准测试中在一些 cpu 密集型任务上的性能略优于 c++ 代码的给定原因。

字节码的“最终编译”还可以做出额外的优化假设,这些假设(从静态编译的角度来看)明显不安全*,如果以后发现这些假设错误,只需重新编译。

于 2011-03-24T14:20:21.607 回答
0

我猜是因为 JIT(及时)编译非常先进。

于 2010-02-28T06:43:17.493 回答