【问题标题】:Why are JIT-ed languages still slower and less memory efficient than native C/C++?为什么 JIT 语言仍然比原生 C/C++ 更慢且内存效率更低?
【发布时间】:2021-02-20 15:57:40
【问题描述】:

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

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

毕竟,Java 内存分配有多好,为什么会有这样的horrendous 内存使用? 2 到 50 倍,平均而言,在该特定基准套件中使用的内存增加了大约 30 倍,这没什么好打喷嚏的......

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

【问题讨论】:

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


【解决方案1】:

产生差异的一些原因;

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

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

  • 在 C++ 中使用 SSE(如果适用,对性能很有帮助)很容易,而在当前 VM 中使用 SSE 很困难

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

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

  • 一些 VM 会创建值类型的对象,例如 int/ulong.. 增加对象内存开销

  • 一些 VM 的自动对齐数据结构会大量浪费内存(以提高性能)

  • 一些 VM 将布尔值实现为 int(4 字节),很少关注内存保护。

【讨论】:

  • +1 这是速度部分的一个很好的答案,愿意分享一些关于内存方面的见解吗?我知道拥有 GC 并为所有内容创建对象具有不平凡的开销。 每个对象有至少一个字的开销(GC元数据),更常见的是两个。
【解决方案2】:

但 C# 或 Java 等语言具有 JIT 编译器,据说可以编译为平台本机机器代码。

口译员最后还必须翻译成机器码。但是 JITters 花费编译和优化的工作量更少,以便更好地启动和执行时间。从用户的角度来看,在编译上浪费时间会使感知到的性能更差,因此只有在 AoT compiler 中只做一次这样的事情才有可能。

他们还必须监控编译结果以进一步重新编译和优化热点,或者取消优化很少使用的路径。然后他们不得不偶尔触发 GC。这些比正常编译的二进制文件花费更多时间。此外,JITter 和 JITted 程序的大量内存使用可能意味着缓存使用效率较低,这反过来也会降低性能

有关内存使用的更多信息,您可以参考here

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

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

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

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

【讨论】:

    【解决方案3】:

    为什么会有如此可怕的内存使用? 2 到 50 倍,平均而言,在该特定基准套件中使用的内存增加了大约 30 倍,这没什么好打喷嚏的......

    https://softwareengineering.stackexchange.com/a/189552

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-21
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      • 2020-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多