避免使用getfield操作码

Syn*_*r0r 30 java bytecode opcode

在Java的String类中,trim方法包含:

int off = offset;      /* avoid getfield opcode */
char[] val = value;    /* avoid getfield opcode */
Run Code Online (Sandbox Code Playgroud)

我对评论"避免getfield操作码"感到有些困惑......

这是什么意思?(我认为这可以避免在字节码中使用getfield,但为什么这是一个Good Thing [TM]?)

难道是防止万一对象创建微调不会做任何事情(因此返回)或?

Jon*_*eet 22

我的猜测是,重点是将值复制到局部变量一次,以避免在接下来的几行中为循环的每次迭代重复从堆中获取字段值.

当然,这就引出了为什么同样的评论没有应用于"len"局部变量的问题.(我还希望JIT无论如何都要避免重新获取,特别是因为变量是最终的.)

  • 注释不适用于'len',因为len在方法中被主动修改,所以它必须是一个局部变量.另一方面,'off'和'val'不会被修改,但仅用于优化. (7认同)
  • @corsiKa:我先编写最简单的代码,然后对其进行分析.如果那提出了微观优化,我*可能已经应用了它. (2认同)

Viv*_*ath 14

getfield 用于获取类的成员变量.

从剩下的代码中可以看出:

while ((st < len) && (val[off + st] <= ' ')) {
    st++;
}
while ((st < len) && (val[off + len - 1] <= ' ')) {
    len--;
}
Run Code Online (Sandbox Code Playgroud)

因此,当您处于循环中时,它必须在getfield每次引用时执行valueoffset.您可以招致大,如果循环时间长(因为每一个循环条件测试时,一个运行性能命中getfield是exeuted两个offsetvalue).因此,通过使用局部变量offval,可以减少性能损失.

  • JIT*可以*优化这个.例如,不要指望在Dalvik上进行这种优化.由于其他原因,将字段拉入本地可能很有用,例如对可以同时访问的字段进行空检查. (6认同)