我知道有一种观点认为,在引入了JIT之后,用Java编写并在JVM下运行的程序与C++程序一样快。我看到许多情况下,与C++相比,Java对于简单程序的速度非常慢,即比等效的C++程序慢2-3倍。
只需给出一个小例子:这是一个简单的基准代码,可以将粒子合并成簇:
https://github.com/chekanov/hepjet
转到"scjet_cpp“并键入" make;make”。它运行C++代码。然后转到"scjet_java“并键入" make;make”。它运行的代码与用Java编写的代码相同。
第一个C++代码在50毫秒内完成粒子合并(i7桌面)。完全相同的Java代码完成170 ms。代码没有什么特别之处,即在C++和Java中实现相同。
有什么评论吗?
发布于 2015-02-10 01:22:03
你的测量可能有缺陷。
还有,你的目标是什么?为了能够说:"Java糟透了,每个人都应该使用C++吗?“这不是特别有建设性的。一个更有建设性的方法是使用您的团队最熟悉的技术(比如Java)构建一个应用程序,然后找到瓶颈,发现只有将项目的这一部分转移到低级语言(包括汇编程序)才能消除它。
发布于 2015-02-10 03:44:46
这个问题没有一个答案,很大程度上是因为它并不总是正确的。事实上,可以说,这从来都不是真的。您不能度量语言的速度,只能测量某些特定实现的速度(甚至很少是整个实现的速度,只能测量它在特定代码块(S)上的执行速度。
Java代码可能比C++代码慢--有时比2或3大得多。
Java代码也可以与C++代码竞争--但是这样做通常需要更多的内存。
对于一些非常具体的东西,Java可以比类似编写的C++更快。
这就是说,是的,平均而言,用Java编写的代码运行速度将比(大致)用C++编写的等效代码慢。如果您主要关注的是执行速度,Java有许多缺点。
主要是它在很大程度上依赖于JIT编译器进行优化--但是由于用户正在等待JIT编译器的运行,所以大多数JIT编译器并不包括最昂贵的优化。由于C++编译器通常只在开发人员等待的情况下运行(或者没有人等待,在基于服务器的CI系统构建的情况下),所以编译器在书中包含每一个优化都要合理得多。
第二个因素是密切相关的: C++供应商认为他们的客户非常关心速度。Java供应商几乎可以肯定地认为,他们的客户更关心的是特性和快速开发,而不是实现绝对最高的执行速度。这并不是说他们能够或确实完全忽视了执行速度,只是他们没有像C++供应商那样强调执行速度。
垃圾收集也会产生影响。Java (通常)使用并发的复制收集器。这在各种各样的工作负载中相当有效,当默认设置不是最优时,大多数JVM都有一些“调优旋钮”来帮助解决。
尽管如此,测试似乎表明,JVM需要比等效的C++代码更多的内存,甚至希望以(大约)相同的速度运行。特别是当您在内存受限的情况下运行时,垃圾收集的开销可能会大幅度增加。这通常不是因为垃圾收集器运行的频率(本身),而是因为当垃圾收集器运行时,许多对象仍然是“活的”。复制收集器的工作方式是将"live“(可达的)对象复制到新位置,因此理想情况下,您希望几乎所有对象在运行之前都是”死的“(不可到达的)。由于内存较少,它不仅运行频率更高,而且每次迭代花费的时间更长,因为更少的对象已经老化到足以“死”,更多的对象仍然可以访问(因此需要复制)。
在运行时完成的工作量与编译时的工作量也有差异。C++高度强调在编译时尽可能多地进行操作。例如,所有很酷的模板“东西”都发生在编译时(在某些情况下,代价是编译时间长得可怕)。尽管语法相似,但很多(大多数?)Java在其泛型系统中对类型的强制执行发生在运行时。Java还包括(和许多Java程序使用的)诸如反射之类的东西,这在C++中根本不存在。
Java还增加了一些方便的特性,比如自动装箱,这使得在看似简单的操作中增加相当多的开销是相当容易的,而这种方式并不是马上就能显现出来的。C++也有一些这样的功能,但是(在我看来)它们的数量都较少,而且它们的有害影响通常比较小(但我对此的看法很可能受到这样一个事实的影响:我对C++的了解要好得多,所以在我看来,类似的问题在C++中可能比在C++中更明显)。
一句话:很难指出Java程序比C++程序慢的一个具体原因。虽然这是真的很多时候,但其发生的原因大不相同,在许多情况下,似乎更多的是“一千个缺口的死亡”,而不是一个单一的因素。
发布于 2015-02-10 04:07:09
至于为什么Java会慢一些:-
虽然java的速度可能比C++慢三倍,但它的速度通常与C++一样快。当您在3 3ghz处理器上运行时,您必须扪心自问这是否真的很重要,因为3 3ghz处理器大部分时间都在等待内存被加载(或者更糟糕的磁盘IO)。
方程的另一个方面(非常主观,但有多年的经验支持)是Java程序的开发速度可以快三倍。工具集功能更强,有大量可供选择的非常好的库,需要注意的问题也有限(没有if (a = b),没有将指针与指向的指针混在一起)。
就我个人而言,在我觉得需要速度的地方,我用普通C语言编写代码,这是一种我非常熟悉的语言,系统性能受限的部分往往很小,而且定义得很好。
所以它的C代表速度。用于生产代码的Java。Groovy或Python用于其他一切!
https://softwareengineering.stackexchange.com/questions/272695
复制相似问题