2012-08-09 82 views
6

解释器做了很多额外的工作,所以它们最终比本地机器代码慢得多,这是可以理解的。但是诸如C#或Java之类的语言都有JIT编译器,据称这些编译器可以编译为平台本地机器代码。为什么JIT编辑语言比原生C/C++更慢,内存效率更低?

然而,根据benchmarks,似乎足够合理,在大多数情况下仍然比C/C++慢2-4倍?当然,我的意思是与同等优化的C/C++代码相比较。我非常了解JIT编译的优化优势以及它们生成的代码的速度比较差优化的C + C++更快。

而且毕竟那些关于Java内存分配有多好的噪音,为什么会这样使用内存? 2倍到50倍,平均每个特定基准测试套件的内存使用量增加了30倍,这对于打喷嚏来说是没有任何作用的...

请注意,我不想启动WAR,定义这些性能和效率数据的技术细节。

+1

..let战争......开始了! – 2012-08-09 10:57:20

+0

[为什么java有缓慢的声誉?](http://stackoverflow.com/questions/2163411/why-did-java-have-the-reputation-of-being-slow) – assylias 2012-08-09 11:00:30

+0

尽管JIT编译器和离线编译器必须平衡编译时间与执行速度,离线编译器可以更多地根据执行速度进行调整。 – harold 2012-08-09 14:18:29

回答

7

有些差异的原因;

  • JIT编译器主要是快速编译并跳过一些需要更长时间才能找到的优化。

  • 虚拟机经常强制安全,这会降低执行速度。例如。数组访问总是界限在.net检查,除非正确的范围内

  • 使用SSE(伟大的性能,如果适用),可保证为C++简单的和困难,从当前的VM的

  • 性能用C得到更多的优先++以上其他方面与虚拟机相比

  • 虚拟机经常保留一段时间未使用的内存,然后返回到似乎'使用'更多内存的操作系统。

  • 一些VM的值类型的化妆对象如int/ULONG ..添加对象的内存开销

  • 一些虚拟机的自动对齐数据结构,大量浪费内存(用于提高性能)

  • 一些虚拟机实现一个布尔型为int(4个字节),对存储器保存很少关注。

+1

+1对于速度部分来说这是一个很好的答案,请分享一些关于内存方面的知识?我知道拥有一个GC并为所有东西创建对象都有非常重要的开销。 *每个*对象至少有*一个开销字(GC元数据),更常见的是两个字。 – delnan 2012-08-09 20:08:09

0

对于存储器可以引用here

爪哇内存使用比C++的内存使用重得多,因为:

  • 没有为每个对象一个8字节的开销[57]而Java中的每个数组[128]都是12字节(32位; 64位java中是两倍)。如果一个对象的大小不是8个字节的倍数,则它被舍入到8的下一个倍数。这意味着包含单个字节字段的对象占用16个字节并且需要4个字节的引用。请注意,C++还为每个声明虚拟函数的对象分配一个指针(通常为4或8个字节)。
  • Java库的部分必须在程序执行之前加载(至少是程序在“底层”使用的类)。[60]这导致小型应用程序的显着内存开销[需要的引证]。
  • Java二进制和本机重新编译通常都在内存中。
  • 虚拟机本身消耗大量内存。
  • 在Java中,使用对B和C的已分配实例的引用创建组合对象(使用B和C实例的类A)。在C++中,这些类型的引用的内存和性能成本可以避免B和/或C存在于A中。
  • 缺乏地址算术使得创建内存有效的容器(例如紧密间隔的结构和异或链表)不可能。

在大多数情况下,由于Java虚拟机的大量开销,类加载和自动调整内存大小,C++应用程序将消耗比等效Java应用程序更少的内存。对于内存是在语言和运行时环境之间进行选择的关键因素的应用程序,需要进行成本/收益分析。

还应该记住,使用垃圾回收器的程序可能需要使用显式内存管理以达到相同性能的程序内存的五倍。

相关问题