在Java中,使用;捷径;变量影响性能?

在Java中,使用;捷径;变量影响性能?,java,Java,我有以下代码: Player player = (Player)Main.getInstance().getPlayer(); player.setSpeedModifier(keyMap[GLFW_KEY_LEFT_SHIFT] ? 1.8f : 1); if (keyMap[GLFW_KEY_W]) { player.moveForward(); } if (keyMap[GLFW_KEY_S]) { player.moveBackward(); } player.rotat

我有以下代码:

Player player = (Player)Main.getInstance().getPlayer();
player.setSpeedModifier(keyMap[GLFW_KEY_LEFT_SHIFT] ? 1.8f : 1);
if (keyMap[GLFW_KEY_W]) {
    player.moveForward();
}
if (keyMap[GLFW_KEY_S]) {
    player.moveBackward();
}
player.rotateTowards(getMousePositionInWorld());
我想知道使用局部变量(对于播放器)使代码更具可读性是否会对性能产生任何影响,或者在编译过程中是否会对其进行优化,以取代变量的使用,因为它只是另一个变量的直接副本。虽然可以保留长版本,但我更喜欢短版本的可读性。我知道,如果有任何影响,对性能的影响将微乎其微,但我只是对是否有任何影响感兴趣


谢谢,-Slendy.

对于任何现代编译器,这很可能会被优化掉,并且不会对性能产生任何影响。用于存储的少数额外字节非常值得增加可读性

除了可能不需要的
(玩家)
演员阵容之外,我甚至发现你的版本比长时间的呼叫更优越

如果您不止一次或两次需要一个特殊对象,那么将其保存在局部变量中是值得的


局部变量在堆栈上需要一些字节,但另一方面,省略了几个调用,因此您的版本显然获胜。

您最大的性能损失可能是对象的函数查找:

(Player)Main.getInstance().getPlayer();
否则,您希望尽可能减少这些函数调用。在这种情况下,本地变量可以节省CPU,但如果您有一个全局变量,使用它可能会快一点


这实际上取决于在一个循环中执行了多少次。在正常使用中,您很可能看不到任何差异。:)

考虑以下两段代码:

final Player player = (Player)Main.getInstance().getPlayer();
player.callmethod1();
player.callmethod2();
以及:

第一种变体更可取的原因如下:

  • 第一个更具可读性,至少因为行的长度
  • Java编译器不能假定相同的对象将由
    Main.getInstance().getPlayer()
    返回,这就是为什么第二个变量将实际调用
    getPlayer
    两次,这可能会导致性能损失

  • 我不认为这会对表现产生影响。一个好的编译器将优化任何一种形式,以便在可能的情况下使用寄存器,并且仅在需要时将最终值写回全局。局部变量也是如此。这里的规则是,在您测量了代码的性能并且知道需要加快它之前,永远不要优化代码。我很好奇编译器是否能够可靠地确定
    Main.getInstance().getPlayer()
    的返回值是否为常量。它可能会,也可能不会。如果没有,我希望没有“快捷方式变量”的版本可能会由于函数调用开销而导致(可以忽略的)执行时间变差。之所以使用player cast,是因为我的代码包含在两个包中。一个有一个模板(BasePlayer),另一个有一个实现(Player)。“我的实例设置”存储了一个BasePlayer,我可以从中实现额外的功能,但为了使用特定于实现的功能,强制转换是必要的。ad 2:JIT可能会识别并优化它,但您的第1点仍然有效,因此首选firsti选项。@glgl true,JIT可能会在运行时识别它,也可能不会,这取决于很多因素,包括月球阶段,所以我不希望完全正确地依赖它。我总是抱怨我的同事给我留下了
    Frobnite(Controller.getInstance().getFoo().getBar().getBaz1(),Controller.getInstance().getFoo().getBar().getBaz2(),Controller.getInstance().getFoo().getBar().getBaz3())而不是可读性非常好的
    Bar=Controller.getInstance().getFoo().getBar();Frobnite(bar.getBaz1(),bar.getBaz2(),bar.getBaz3())。如果getPlayer()返回的变量(如果它的返回值甚至绑定到一个成员变量!据我们所知,它可能返回随机垃圾)不是最终变量(可能还有我不知道的其他修饰符和条件),那么阅读起来很好,一眼就可以理解,JIT无法知道没有其他线程更改了它的返回值。存储在实例中的Player变量基本上只在玩家选择采取将改变它的行动时设置,而不是在任何预定点设置。如果玩家选择加载游戏,它将被覆盖,就像他们开始新游戏时一样。
    
    ((Player)Main.getInstance().getPlayer()).callmethod1();
    ((Player)Main.getInstance().getPlayer()).callmethod2();