比如以下一段java代码:
private void performTraversals() {
// cache mView since it is used so much below...
final View host = mView;
......
}
为什么要这么写呢?
下面用一段测试程序的bytecode来解释一下(以下bytecode是基于JVM的,不是基于art的):
public class TestLocal {
private int i = 1;
public void foo() {
long before = System.currentTimeMillis();
for (int j = 0; j < 10000; j++) {
System.out.print(i);
}
System.out.println();
System.out.println("TestLocal result: " + (System.currentTimeMillis() - before));
}
public static void main(String[] args) {
new TestLocal().foo();
new TestLocal2().foo();
}
}
class TestLocal2 {
private int i = 1;
public void foo() {
int k = i;
long before = System.currentTimeMillis();
for (int j = 0; j < 10000; j++) {
System.out.print(k);
}
System.out.println();
System.out.println("TestLocal2 result: " + (System.currentTimeMillis() - before));
}
}
TestLocal
的foo
方法,直接读取类变量,对应的字节码是
13: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
16: aload_0
17: getfield #2 // Field i:I
20: invokevirtual #5 // Method java/io/PrintStream.print:(I)V
每次都需要将this push到operand stack中,然后去堆里找对应的field。
而TestLocal2
的foo
方法,是将类变量的值存储在当前Frame的local variable中。然后每次调用只要从local variable中取用。
0: aload_0
1: getfield #2 // Field i:I
4: istore_1
.......
20: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
23: iload_1
24: invokevirtual #5 // Method java/io/PrintStream.print:(I)V
运行时间对比:
TestLocal result: 145 ms
TestLocal2 result: 128 ms
所以将类变量缓存到方法的local variable中还是能提升运行速度的,尤其是如果类变量会被经常访问。