有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

现代Java编译器/JVM内联函数/方法完全从一个地方调用,性能如何?

I found out that the C++ compiler does so,但我想知道java编译器是否也这么做,因为在那个答案中,添加静态会这样做,但是java和C++中的静态是不同的。在我的例子中,性能很重要,因为我使用的函数在游戏循环中每帧只调用一次,而在其他任何地方都不会调用,以使其更具可读性
在我的代码中,我的设置与此类似,只是有更多的调用

while(running)
{
    update();
    sync();
}

然后update(),render()将调用更多调用其他方法的方法

private final void update()
{
    switch(gameState)
    {
        case 0:
            updateMainMenu();
            renderMainMenu();
            break;
        case 1:
            updateInGame();
            renderInGame();
            break;
         //and so on
    }
}

private final void updateInGame()
{
    updatePlayerData();
    updateDayCycle();
    //and so on
}

private final void updatePlayerData()
{
    updateLocation();
    updateHealth();
    //and so on
}

那么,编译器是否会内联这些函数,因为它们在同一位置每帧只使用一次

如果这是一个糟糕的问题,请告诉我,我会删除它


共 (2) 个答案

  1. # 1 楼答案

    Java JITC将尝试内联任何出现(基于运行时统计数据)的函数,这些函数的调用频率足以使其发挥作用。不管函数是在一个地方调用,还是在几十个地方调用,每个调用站点都会被单独分析

    注意,这个决定是基于几个因素。如果有很多潜在的内联候选者,那么这个方法有多大,只有最有利可图的才会内联,以避免“代码膨胀”。但通话频率(乘以通话的感知费用)是最大的“得分”因素

    阻止内联的一件事是明显的多态调用。如果调用可能是多态的,那么它必须由代码“保护”,如果到达的类不是预期的类,则代码将执行原始调用。如果统计数据证明一个调用经常是多态的(并且包含所有多态变量是不值得的),那么内联调用可能没有足够的利润。静态或最终方法是最有吸引力的,因为它不需要保护

    另一件会阻碍内联(以及其他很多东西)的事情是,奇怪的是,无法从方法返回。如果有一个方法被输入,然后在内部循环1000万次而没有返回,那么JITC永远不会有机会“交换”已解释的方法和“交换”已编译的方法。但是JITC在一定程度上克服了这一点,它使用的技术只编译方法的一部分,而对其余部分进行解释

  2. # 2 楼答案

    作为将来的参考,您可以查看。用javap -c MyClass初始化文件,以查看编译后的代码

    回答你的问题:Java编译器不内联方法。另一方面,JVM会分析代码,并在必要时在运行时内联。基本上,你不应该担心它,把它留给JVM,如果它觉得有用的话,它会内联。在这些方面,JVM通常比您更聪明


    http://www.oracle.com/technetwork/java/whitepaper-135217.html#method

    Method Inlining
    The frequency of virtual method invocations in the Java programming language is an important optimization bottleneck. Once the Java HotSpot adaptive optimizer has gathered information during execution about program hot spots, it not only compiles the hot spot into native code, but also performs extensive method inlining on that code.

    Inlining has important benefits. It dramatically reduces the dynamic frequency of method invocations, which saves the time needed to perform those method invocations. But even more importantly, inlining produces much larger blocks of code for the optimizer to work on. This creates a situation that significantly increases the effectiveness of traditional compiler optimizations, overcoming a major obstacle to increased Java programming language performance.

    Inlining is synergistic with other code optimizations, because it makes them more effective. As the Java HotSpot compiler matures, the ability to operate on large, inlined blocks of code will open the door to a host of even more advanced optimizations in the future.