为什么JIT-ed语言比原生C / C ++更慢,内存效率更低?

时间:2012-08-09 10:55:59

标签: performance memory-management native jit machine-code

口译员做了很多额外的工作,因此可以理解的是,它们最终比本机机器代码慢得多。但是像C#或Java这样的语言有JIT编译器,据说可以编译成平台本机代码。

然而,根据benchmarks看起来足够合法,在大多数情况下仍然比C / C ++慢2-4倍?当然,我的意思是与同等优化的C / C ++代码相比。我非常清楚JIT编译的优化优势以及它们生成比优化不佳的C + C ++更快的代码的能力。

在关于Java内存分配有多好的所有噪音之后,为什么这样的horrendous内存使用? 2x到50x,在特定的基准测试套件中平均使用的内存大约多30倍,这没什么可打喷嚏的......

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

3 个答案:

答案 0 :(得分:7)

差异的一些原因;

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

  • VM通常会强制执行安全性,这会降低执行速度。例如。除非保证在正确的范围内,否则数组访问始终在.Net中进行检查

  • 使用SSE(如果适用的话,性能很好)很容易从C ++中获取,而在当前虚拟机中很难

  • 与VM相比,性能在C ++中优先于其他方面

  • 在返回操作系统似乎“使用”更多内存之前,VM通常会将未使用的内存保留一段时间。

  • 某些VM制作类型为int / ulong的对象..添加对象内存开销

  • 某些VM的自动对齐数据结构浪费了很多内存(性能提升)

  • 有些VM实现了一个boolean作为int(4个字节),很少关注memoryconservation。

答案 1 :(得分:0)

对于记忆,您可以参考here

  

Java内存使用量比C ++的内存使用量要重得多,因为:

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

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

     

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

答案 2 :(得分:0)

  

为什么这么可怕的内存使用? 2x到50x,在特定的基准测试套件中平均使用的内存大约多30倍,这没什么可打喷嚏的......

请参阅https://softwareengineering.stackexchange.com/a/189552