首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么Java比同等的C++程序慢2-3个因素?

为什么Java比同等的C++程序慢2-3个因素?
EN

Software Engineering用户
提问于 2015-02-10 01:04:31
回答 4查看 14.4K关注 0票数 3

我知道有一种观点认为,在引入了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中实现相同。

有什么评论吗?

EN

回答 4

Software Engineering用户

发布于 2015-02-10 01:22:03

你的测量可能有缺陷。

  1. 如果您只是运行这两个应用程序并在终端中从开始到结束测量时间,那么您不是在测量执行时间,而是在测量启动时间。对于Java应用程序,这意味着这170毫秒。还包含JIT编译。
  2. 此外,50 ms。对170毫秒。没有代表性。在一个循环中完成一项任务,得到50名s,而170名将更有意义。
  3. 你不能只拿一个项目说:“这个语言更好,因为这个特定的项目用这个语言执行得更快。”一个项目没有足够的代表性。也许作者对C++的了解比Java更多。也许他们错过了优化代码的机会。
  4. 您使用的编译器可能会产生很大的不同。有些人会创建性能糟糕的代码。其他人将使用聪明的优化技术。

还有,你的目标是什么?为了能够说:"Java糟透了,每个人都应该使用C++吗?“这不是特别有建设性的。一个更有建设性的方法是使用您的团队最熟悉的技术(比如Java)构建一个应用程序,然后找到瓶颈,发现只有将项目的这一部分转移到低级语言(包括汇编程序)才能消除它。

票数 36
EN

Software Engineering用户

发布于 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++程序慢的一个具体原因。虽然这是真的很多时候,但其发生的原因大不相同,在许多情况下,似乎更多的是“一千个缺口的死亡”,而不是一个单一的因素。

票数 16
EN

Software Engineering用户

发布于 2015-02-10 04:07:09

至于为什么Java会慢一些:-

  • JVM需要解释伪机器代码,C++盲目地执行本机代码。
  • JVM管理内存,C++则由程序员来管理内存,它更高效,但也更容易出错。
  • JVM需要启动,然后加载和解释各种类;使用C++程序,加载基本上是将指令从磁盘复制到内存,在许多情况下(使用DLL、.so、共享库等)。程序将已经加载,并已在内存中准备就绪。这实际上是Java最大的性能问题,使得该语言完全不适合在短时间内独立执行。

虽然java的速度可能比C++慢三倍,但它的速度通常与C++一样快。当您在3 3ghz处理器上运行时,您必须扪心自问这是否真的很重要,因为3 3ghz处理器大部分时间都在等待内存被加载(或者更糟糕的磁盘IO)。

方程的另一个方面(非常主观,但有多年的经验支持)是Java程序的开发速度可以快三倍。工具集功能更强,有大量可供选择的非常好的库,需要注意的问题也有限(没有if (a = b),没有将指针与指向的指针混在一起)。

就我个人而言,在我觉得需要速度的地方,我用普通C语言编写代码,这是一种我非常熟悉的语言,系统性能受限的部分往往很小,而且定义得很好。

所以它的C代表速度。用于生产代码的Java。Groovy或Python用于其他一切!

票数 1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/272695

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档