比如以下一段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中還是能提升運行速度的,尤其是如果類變量會被經常訪問。