14

Java 很慢。

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

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

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

还有很多“Java 比 X 更快”,也有(例如,这里有一个关于 SO:Java Runtime Performance Vs Native C / C++ Code?的问题)。

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

为什么在某些情况下,在给定动态代码(Scala、Clojure)和垃圾收集的情况下,字节码可能比本机代码运行得更快?如果它更快,为什么还有延迟?

这似乎是一个矛盾,有人可以解释一下吗?

4

5 回答 5

11

在《编程大师》一书中,James Gosling 解释说:

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

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

于 2011-04-12T21:09:28.233 回答
9

快速 JVM 使用即时 (JIT) 编译。字节码在运行时即时翻译为本机代码。JIT 提供了许多优化机会。有关 JIT 的更多信息,请参阅此 Wikipedia 文章

于 2011-04-12T20:44:43.570 回答
4

JVM 有多种形式!

最快的将字节码动态编译为本机代码,基于收集的性能特征。所有这些都需要额外的内存,因此他们以内存为代价来购买速度。此外,最高速度需要一段时间才能达到,因此短期程序不会显示好处。

即便如此,JamVM解释器(与 Oracle JVM 相比很小)仍能达到已编译 JVM 合理比例的最高速度。

关于垃圾收集,速度再次来自有足够的可用内存。真正的好处还来自于从代码中删除了跟踪对象何时不再使用的责任。这导致程序更简单、更不容易出错。

于 2011-04-12T20:44:49.623 回答
3

好吧,这是一个古老的论点。几乎所有流行的 Emacs 和 VI。(但绝对没有那么旧)。我看到很多 c++ 开发人员就为什么大多数性能基准测试(特别是提到 java 与 c++__ 一样快)存在偏差提出了很多论据,老实说,他们有道理。

我没有足够的知识或时间来深入了解 Java 如何能像 C++ 一样快,但以下是它可能的原因......

1-当您要求两个非常有能力的开发人员用 Java 和 C++ 编写代码来解决现实世界的问题(相同的问题)时,如果 java 的执行速度比 C++ 快,我会感到惊讶。编写良好的 C++ 使用 Java 将使用的一小部分内存。(Java 对象稍微臃肿一些)。

2- Java 本质上是一种更简单的语言,它的编写是为了确保难以编写次优代码。通过抽象内存管理以及处理低级优化,用 Java 编写比 C++ 更好的代码更容易。(我认为这是最重要的事情......很难用 Java 编写糟糕的代码)。另一方面,一个好的 C++ 开发人员可以比 Java 中的自动 GC 更好地处理内存管理。(Java 将所有内容存储在堆中,因此使用更多内存......)

3- Java 编译器不断得到改进,热点之类的想法已被证明比营销术语更好。(当引入 JIT 时,它只是一个营销术语.. 据我所知.. :))

4- 人体工程学或根据底层操作系统参数定制设置使 java 处理变化更好。因此,在某些环境中,不难想象 Java 的性能与 C++ 一样好。

5- 为 Java 开发人员开放高级并发和并行 API 也是一个原因。Java 并发包可以说是编写可以利用当今多处理器环境的高性能代码的最简单方法。

6- 随着硬件变得越来越便宜,开发人员的能力已经成为一个更大的因素,这就是为什么我相信很多 c++ 代码可能比 Java 慢。

于 2011-04-12T21:04:11.230 回答
2

Java 字节码比大多数原生操作码更容易优化。因为字节码是有限制的,不能做一些危险的事情,所以可以优化得更充分。以指针别名为例。http://en.wikipedia.org/wiki/Pointer_aliasing

在 c/c++ 中你可以做

char[] somebuffer = getABuffer();
char* ptr = &someBuffer[2];
memcpy(ptr, somebuffer, length);

这使得在某些情况下难以优化,因为您无法确定什么指的是什么。在 Java 中,这种事情是不允许的。

通常,您可以在更高抽象级别上执行的代码突变比在目标代码上执行的代码更强大。

于 2011-04-12T20:54:15.527 回答