我正在做一些測試,以找出使用getters/setters和直接字段訪問之間的速度差異。我寫了一個簡單的基準測試應用程序是這樣的:爲什麼Method訪問看起來比Field訪問更快?
public class FieldTest {
private int value = 0;
public void setValue(int value) {
this.value = value;
}
public int getValue() {
return this.value;
}
public static void doTest(int num) {
FieldTest f = new FieldTest();
// test direct field access
long start1 = System.nanoTime();
for (int i = 0; i < num; i++) {
f.value = f.value + 1;
}
f.value = 0;
long diff1 = System.nanoTime() - start1;
// test method field access
long start2 = System.nanoTime();
for (int i = 0; i < num; i++) {
f.setValue(f.getValue() + 1);
}
f.setValue(0);
long diff2 = System.nanoTime() - start2;
// print results
System.out.printf("Field Access: %d ns\n", diff1);
System.out.printf("Method Access: %d ns\n", diff2);
System.out.println();
}
public static void main(String[] args) throws InterruptedException {
int num = 2147483647;
// wait for the VM to warm up
Thread.sleep(1000);
for (int i = 0; i < 10; i++) {
doTest(num);
}
}
}
每當我運行它,我得到一致的結果,如這些:http://pastebin.com/hcAtjVCL
我想知道,如果有人可以給我爲什麼現場訪問,似乎要慢一些解釋比getter/setter方法的訪問,以及爲什麼最後8次迭代執行得非常快。
編輯:經考慮assylias
和Stephen C
意見,我已經改變了代碼http://pastebin.com/Vzb8hGdc那裏我得到了略有不同的結果:http://pastebin.com/wxiDdRix。
我認爲編譯器內聯了getters。你檢查過字節碼嗎? – jlordo 2013-02-12 11:57:09
'/ *等待VM預熱*/Thread.sleep(1000);' - 這不是它的工作原理。如果JVM沒有做任何事情,它就不會升溫......你的微基準有幾個缺陷。特別是:(i)您並不真正允許JVM進行預熱(ii)您要測試的兩個路徑採用相同的方法,這可能會阻止某些優化。 – assylias 2013-02-12 11:58:53
@jlordo - 內聯由JIT編譯器完成。我將不會在字節碼中看到。 – 2013-02-12 11:59:12