java什么时候比c++;(或者JIT何时比预编译快)?

java什么时候比c++;(或者JIT何时比预编译快)?,java,performance,optimization,compiler-construction,jit,Java,Performance,Optimization,Compiler Construction,Jit,可能重复: 我听说在某些情况下,Java程序或相当部分java程序能够比C++中的“相同”代码更快地执行(或其他预编译代码),这是因为java优化。这是因为编译器能够确定一些变量的范围,避免一些条件,并在运行时使用类似的技巧 你能举一个(或更好的)例子吗?并且可能概述编译器能够优化字节码的确切条件,使其超出预编译代码的可能范围 注:这个问题不是关于java和C++的比较。这是关于JIT编译的可能性。请不要燃烧。我也不知道有任何重复。如果是,请指出它们。维基百科: 此外,在某些情况下,它可以提供

可能重复:

<>我听说在某些情况下,Java程序或相当部分java程序能够比C++中的“相同”代码更快地执行(或其他预编译代码),这是因为java优化。这是因为编译器能够确定一些变量的范围,避免一些条件,并在运行时使用类似的技巧

你能举一个(或更好的)例子吗?并且可能概述编译器能够优化字节码的确切条件,使其超出预编译代码的可能范围

注:这个问题不是关于java和C++的比较。这是关于JIT编译的可能性。请不要燃烧。我也不知道有任何重复。如果是,请指出它们。

维基百科:

此外,在某些情况下,它可以提供比静态编译更好的性能,因为许多优化只在运行时可行:

  • 编译可以针对目标CPU和应用程序运行的操作系统模型进行优化。例如,JIT可以在检测到CPU支持SSE2 CPU指令时选择这些指令。为了使用静态编译器获得这种优化特性,必须为每个预期的平台/体系结构编译一个二进制文件,或者在一个二进制文件中包含代码部分的多个版本

  • 系统能够收集有关程序在其所在环境中实际运行情况的统计信息,并且可以重新排列和编译以获得最佳性能。然而,一些静态编译器也可以将配置文件信息作为输入

  • 系统可以进行全局代码优化(例如库函数的内联),而不会失去动态链接的优势,也不会产生静态编译器和链接器固有的开销。具体来说,在执行全局内联替换时,静态编译过程可能需要运行时检查,并确保在对象的实际类重写内联方法时会发生虚拟调用,并且可能需要在循环中处理数组访问的边界条件检查。在许多情况下,使用即时编译,可以将此处理移出循环,通常会大大提高速度

  • 虽然静态编译的垃圾收集语言可以做到这一点,但字节码系统可以更容易地重新排列执行的代码,以获得更好的缓存利用率

  • 一些例子:

    • JIT编译器可以使用最新的SSE扩展生成非常特定于CPU的机器代码,这些扩展在需要运行大量CPU的预编译代码中是不会使用的
    • JIT知道虚拟方法(Java中的默认方法)何时不会在任何地方被覆盖,因此可以内联(尽管这需要在加载了覆盖该方法的新类时取消内联;当前的Java JIT编译器实际上会这样做)
    • 与此相关,允许一些特定于具体情况的优化

    Java的内存管理比C++快得多。在实践中,你可能会发现你的java编写的代码在这些情况下比你的天真的C++代码要出色(我都亲自观察过):

    • 大量少量内存分配/释放。主要的JVM都有非常高效的内存子系统,垃圾收集可以比显式释放更高效(此外,如果它真的愿意,还可以移动内存地址等等)

    • 通过方法调用的深层层次结构进行高效访问。JVM非常擅长于任何不必要的事情,通常我的经验比大多数C++编译器(包括GCC和ICC)都要好。在某种程度上,这是因为它可以在运行时进行动态分析(也就是说,它可能会过度优化,只有在检测到问题时才会取消优化)

    • 将功能封装到小型短期对象中


    在每种情况下,如果你努力,C++可以做得更好。(在空闲列表和块分配/释放内存之间,C++几乎可以在每种特定情况下击败JVM内存系统;使用额外的代码、模板和智能宏,可以非常有效地折叠调用堆栈;并且可以在C++中拥有部分初始化的堆栈分配对象,这些对象优于JVM的短时间对象模型)。但是,你可能不想把精力放进去。

    第一个点是另外有效的,因为在新的CPU架构之前,许多java库都是编写的。这些旧的库仍然使用最新的CPU改进。为了利用C++中最新的体系结构,你必须能够从源编译许多不可的。可能/适用于第三方库。特别是如果开发人员不是最终用户。例如,您有一个应用程序必须部署到许多不同类型的PC上,发布每一个可能的平台可能是一场噩梦,因此通常会选择最低的通用去噪器。我相信JIT可以执行多态内联。即,它知道多达两种可能的“虚拟”方法通常被调用,这些可以被内联,如果对象不是这些类中的一个,则存在回落。这意味着即使是多个可能实现的虚拟方法也可以基于运行时行为来内联。C++配置的优化器使用这些相同的技巧。C++ C++并不要求你使用<代码> MalOC < /C> >,例如,查看WiReSalk的池分配程序。因此,这个参数不适用于C++的新的分配。这是因为HeapAlloc和Apple分配的堆用于分配新的大信息,但是仔细阅读显示了