Java运行时性能与本机C / C ++代码?

时间:2009-12-31 10:30:34

标签: java c++ c jvm

我越来越习惯使用Java编程而不是使用C ++或C.我希望能够了解使用JVM解释器所带来的性能损失,而不是本机执行相同的“项目”。我意识到这里有一定程度的主观性;该计划的质量将在很大程度上取决于良好的实施。我对一般意义上的以下几个方面感兴趣:

  • 使用解释器时必须有一些开销基线。是否有一些一般的经验法则要记住? 10%15%? (我凭空掏出这些数字)我偶尔读过一篇博客,说Java代码几乎和本机代码一样快,但我认为这可能有偏见。

  • JVM垃圾收集器是否会为运行时性能增加大量开销?我知道Cocoa应用程序已经开始使用垃圾收集模型,我同意它使编程变得更简单,但代价是什么?

  • 从Java进行系统调用的开销是多少?例如,创建Socket对象而不是C套接字API。

  • 最后,我回想一下JVM实现是单线程的。如果这是真的(我对此持怀疑态度),这是否意味着Java线程真的不是真正的线程?通常,java线程是否与底层内核提供的线程相对应? Java应用程序是否与本机应用程序来自多个核心/多个CPU的方式相同?

了解JVM和Java程序性能的复杂性的开发人员的任何建议都将非常感激。感谢。

11 个答案:

答案 0 :(得分:48)

答案 1 :(得分:16)

请参阅here,了解详细信息。

答案 2 :(得分:5)

java和c#(以及objective-c)都没有本机代码那么快。但这只有在您遇到工程时限的问题时才有意义。因为您将有时间使用高级语言设计更好的算法。

所以基本上,如果你正在开发一种设备,你要建造一年一百万,或者电池供电,你就不用java或c#来构建它的核心功能。但是,您可以添加lisp解释器以轻松实现自定义。微软不打算用c#作为SQL服务器的核心,而性能真的很重要。另一方面,MS可以期望用户拥有高端硬件,可以用作慢速但高生产率技术的展示。

请注意,我目前在Pharo Smalltalk中进行大部分编程,这比java,c#或objective-c慢很多,甚至不是最快的Smalltalks之一。生产力胜过绩效。

答案 3 :(得分:2)

解决您的每一点:

  • 解释代码的开销远远高于10-15%(我猜的是3x-5x或更高)。为了降低到10-15%,你必须使用某种形式的机器代码编译步骤(即JIT)。 (尝试在关闭JIT的情况下运行JVM,你会看到性能下降就像摇滚一样。)
  • 垃圾收集确实会对性能产生影响,但我会说每个人都同意这是值得的。如果您能负担字节码编译/解释开销,那么您也可以承担gc开销。
  • 在Java中,套接字编程比在C / C ++中容易得多,如果这就是你所要求的。从性能上讲,套接字I / O开销在Java执行开销上占主导地位。
  • 大多数现代JVM都有真正的线程,即每个Java线程都由内核线程执行,允许Java线程利用现代多核CPU。

答案 4 :(得分:2)

很多人低估了java的性能。我曾经对此感到好奇,并在java中编写了一个简单的程序,然后在c中编写了一个等价的程序(除了用for循环和一个大型数组做一些操作)。我不记得确切的数字,但我知道当c程序没有使用任何优化标志(在gcc下)编译时,java击败了c。正如预期的那样,当我最终用积极优化编译它时,c领先。说实话,这不是一个科学实验,但确实给了我一个了解java所处位置的基线。

当然,当你开始做需要系统调用的事情时,java可能会进一步落后。虽然,我已经看到100MB / s的磁盘和网络读取性能与在适度硬件上运行的java程序。不知道究竟是什么说的,但它确实向我表明它对于我需要的任何东西都足够好。

对于线程,如果你的java程序创建了2个线程,那么你有2个真正的线程。

答案 5 :(得分:1)

答案 6 :(得分:1)

实际上,VM可以在运行时根据C / C ++编译器无法完成的仅在运行时可用的信息进行大量优化。因此,在大多数情况下,JVM至少与本机程序一样快。

Brian Goetz在他的演讲Towards a universal VM中回答了大部分问题(如果不是全部问题)。

答案 7 :(得分:0)

这个问题没有一个简单的答案。编写C风格的C ++是可能的(甚至是个好主意),但是一旦你尝试在C中继承,事情就会变得难看。因此,忽略C并使用 Java -vs-C ++ ,因为它们彼此更接近。

要真正了解它,您需要在两种语言中以类似的方式编写两个相对较大的应用程序。如果你这样做,那么你是使用STL和Java集合类,还是自己编写并在语言之间移植它们?如果你使用原生的那个,那么它取决于哪个实现更快,就像你使用自己的实现一样,你没有测试应用程序的实际速度。

我会说你需要尽可能地编写应用程序,但是在有意义的地方使用特定于语言的库/习语。 C ++和Java代码虽然相似,却有不同的处理方式 - 在Java中使用简单的东西在C ++中可能非常难,反之亦然。

现代GC实现不会增加太多开销,如果您愿意,可以切换到GC in C++进行比较: - )

Java运行时可以做的一些事情通常不会在C ++编译器中完成,例如内联虚拟方法的能力。

对于系统类型的东西,Java通常会调用C调用,因此存在开销(尽管JNI比以前更快)。

线程取决于实现。 Sun过去常常使用“绿色线程;对于Solaris,但已经很久了。据我所知最多(全部?),现代虚拟机使用本机线程。

简而言之,我认为Java -vs-C ++的开销百分比并不是一个好的指标,而且你发现的任何一个都可能是不代表现实世界的微基准(不幸的是)。

答案 8 :(得分:0)

需要记下的重要事项是

Java字节码JIT编译为特定于特定硬件的更优化代码

VS

为一般硬件编译和优化的C代码,因此无法利用特定硬件提供的功能

答案 9 :(得分:0)

由于你的目标是非常适度的“我希望能够理解性能......”你应该能够通过检查<中显示的程序和测量来完成大部分工作。 strong>计算机语言基准游戏。

如您所知,Java和C ++

但你必须思考关于whether measurements of tiny programs can plausibly indicate the likely performance of your application

答案 10 :(得分:0)

如今的多线程和分布式模式消除了对本机速度的需求,Java 可以达到 C++ 速度,并且在某些情况下可以更快,但总的来说,我们可以说 C++ 比 Java 快一点,可以说是 10-20%,这可以通过在负载均衡器之后添加另一个服务来忽略,因此 4 个 c++ 服务可以做什么 5 个 java 服务可以以相同的速度执行,3 个 c++ 线程可以做什么 4 个 java 线程可以以相同的速度执行。 另一个重要因素是代码本身,好的java代码可以比坏的c++代码更快,java有更大的社区和更强的支持以及更稳定的库和工具。 所以对于服务器端 java 是更好的选择,可以节省时间并导致更稳定和高性能的代码