ゲッター/セッターと直接フィールドアクセスを使用するときの速度の違いを調べるためにいくつかのテストを行っていました。私はこのような単純なベンチマークアプリケーションを書いた:メソッドアクセスがフィールドアクセスより速いように見えるのはなぜですか?
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回の反復が信じられないほど高速に実行される理由もあります。
編集:http://pastebin.com/wxiDdRix:アカウントへassylias
とStephen C
コメントを取られたので、私は私がわずかに異なる結果を得たhttp://pastebin.com/Vzb8hGdcにコードを変更しました。
私はコンパイラがゲッターをとにかくインライン化すると思います。バイトコードをチェックしましたか? – jlordo
'/ * VMがウォーミングアップするのを待つ*/Thread.sleep(1000);' - それは動作しません。 JVMは何もしなければウォーミングアップしません...あなたのマイクロベンチマークにはいくつかの欠陥があります。特に、(i)JVMのウォームアップを許可していない(ii)テストする2つのパスが同じメソッドにあるため、いくつかの最適化を妨げる可能性があります。 – assylias
@jlordo - インライン展開はJITコンパイラによって行われます。私はバイトコードで明白ではないでしょう。 –