任何人都可以量化C++和Java之间的性能差异吗?

2022-09-03 03:08:54

Java在JIT之前最初很慢,但今天的性能非常接近C++。我想知道是否有人在两种语言之间进行了可衡量的性能比较?与C++相比,Java的不足之处在哪里?Java为开发人员提供了许多生产力提升,因此由于垃圾学院,缺乏指针等原因,他们可以更快地编写应用程序。例如,Firefox,Webkit和Open Office等应用程序如果用100%Java编写,可以更快,更可靠地开发,也许是2倍,但出于性能原因,开发人员仍然选择C / C++。有人可以证明Java不能在哪些地方表现得像我提到的那些应用程序那样C++。

让我补充一点,出于某种原因,C++仍在进行大量应用程序工作。这不仅仅是一个主观问题。具有较高抽象级别的语言通常会降低性能。如果这种惩罚不存在,我们都会用更高级的语言编程。与C++相比,Java还在哪里付费?要具体。


答案 1

语言没有速度。Java或C++语言规范都没有指定“并且必须编译程序才能如此高效”。

每种语言都指定了程序必须执行的操作列表,或者至少看起来要执行的操作,这在某些情况下对程序的效率设置了上限,但通常,聪明的编译器可以在单个程序中忽略这些规则,因为重要的是程序的行为就像遵循规范一。函数可以内联,堆数据可以移动到堆栈等等。

程序的性能取决于三件事:编译器,底层平台/硬件和程序代码本身。

不是“语言”。最接近的是编译器。

有充分的理由说明为什么任何一种语言可能比另一种语言更快。C++做出的承诺较少,这可能会减慢程序执行速度,但Java是JIT的,这意味着它可能会利用运行时信息来优化代码,而C++无法轻易做到......再说一遍,规范中没有任何地方说C++不能被jit'ed。就像我相信还有Java编译器生成本机代码而不是JVM字节码一样。

只有当您运行特定的计算机,每种语言的特定编译器以及每种语言的程序的特定实现时,您的问题才有意义,在这种情况下,您可以同时运行这两种计算机以查看哪个速度最快

垃圾回收是另一个很好的例子。当然,垃圾回收意味着一些开销,但它也启用了一些重要的快捷方式。在 Java 或 .NET 等托管语言中,堆分配非常便宜,因为它是托管的和垃圾回收的。在C++,它是....当然,未指定,但在实践中,通常非常慢,因为操作系统必须遍历堆才能在或多或少碎片化的内存空间中找到可用的内存块。哪个是最快的?取决于操作系统。取决于编译器。取决于源代码。

源代码也有很大的不同。如果你拿一个Java程序,天真地把它移植到C++,它就会像废话一样运行。C++不能很好地处理虚拟功能,并且通常可以使用更好的替代方案。C++,堆分配可能非常慢,因此,天真地重新实现Java程序将非常低效。反之亦然。许多C++习语如果直接移植到Java,就会变得不必要地慢。因此,即使您已经确定了一个平台和一个编译器,您如何比较程序的性能?为了让它进入编译器,你必须编写它的两个实现,然后它就不再是同一个程序了。

但是,我认为公平地说,在大多数现代硬件上,使用现代Java编译器和现代C++编译器,大多数程序都可以实现得非常高效,而且肯定足够快。但前提是你理解你正在使用的语言,并遵守它的规则。如果你尝试用C++编写Java代码,那么Java将神奇地变得更加高效,反之亦然。

我想对你的问题最简洁的答案是“不。没有人能量化C++和Java之间的性能差异“;)


答案 2

对于许多单独的代码构造,JIT 编译器可以更快,因为它们可以利用代码的运行时分析。

例如,VonC 在回答此问题时提到了所有对象的堆分配。实际上并非如此:如果 JIT 可以通过转义分析证明对对象的引用不会超过堆栈帧,则 JIT 可以在堆栈上分配对象。通过这种方式,编译器可以获得堆栈分配的性能优势,而程序员可以放心假设GC堆分配的安全性。

类似地,Uri提到了虚函数(在大多数非C++语言中称为虚方法)。这是JIT编译器具有提前(AOT)编译器几乎永远无法使用的优势的另一种情况:JIT可以插入内联的廉价类型检查(取消引用的单词比较),并且如果该特定调用站点恰好是单态的(即实际类型在实践中始终相同),则实际上内联虚拟方法调用。事实证明,在实践中,高达95%的虚拟方法调用都是单态的,因此这可能是一个相当大的胜利 - 这是AOT编译器难以利用的胜利,因为运行时代码加载可能会动态更改运行时特征。


推荐