现代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
}
那么,编译器是否会内联这些函数,因为它们在同一位置每帧只使用一次
如果这是一个糟糕的问题,请告诉我,我会删除它
# 1 楼答案
Java JITC将尝试内联任何出现(基于运行时统计数据)的函数,这些函数的调用频率足以使其发挥作用。不管函数是在一个地方调用,还是在几十个地方调用,每个调用站点都会被单独分析
注意,这个决定是基于几个因素。如果有很多潜在的内联候选者,那么这个方法有多大,只有最有利可图的才会内联,以避免“代码膨胀”。但通话频率(乘以通话的感知费用)是最大的“得分”因素
阻止内联的一件事是明显的多态调用。如果调用可能是多态的,那么它必须由代码“保护”,如果到达的类不是预期的类,则代码将执行原始调用。如果统计数据证明一个调用经常是多态的(并且包含所有多态变量是不值得的),那么内联调用可能没有足够的利润。静态或最终方法是最有吸引力的,因为它不需要保护
另一件会阻碍内联(以及其他很多东西)的事情是,奇怪的是,无法从方法返回。如果有一个方法被输入,然后在内部循环1000万次而没有返回,那么JITC永远不会有机会“交换”已解释的方法和“交换”已编译的方法。但是JITC在一定程度上克服了这一点,它使用的技术只编译方法的一部分,而对其余部分进行解释
# 2 楼答案
作为将来的参考,您可以查看。用
javap -c MyClass
初始化文件,以查看编译后的代码回答你的问题:Java编译器不内联方法。另一方面,JVM会分析代码,并在必要时在运行时内联。基本上,你不应该担心它,把它留给JVM,如果它觉得有用的话,它会内联。在这些方面,JVM通常比您更聪明
从http://www.oracle.com/technetwork/java/whitepaper-135217.html#method