6

ゲッター/セッターを使用する場合とフィールドに直接アクセスする場合の速度の違いを調べるために、いくつかのテストを行っていました。私は次のような簡単なベンチマークアプリケーションを作成しました。

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

4

1 に答える 1

9

説明は、ベンチマークが壊れているということです。

最初の反復はインタープリターを使用して行われます。

Field Access:  1528500478 ns
Method Access: 1521365905 ns

2 番目の反復は、最初にインタープリターによって行われ、その後、JIT コンパイル済みコードの実行に切り替わります。

Field Access:  1550385619 ns
Method Access: 47761359 ns

残りの反復はすべて、JIT コンパイル済みコードを使用して行われます。

Field Access:  68 ns
Method Access: 33 ns

etcetera

それらが信じられないほど高速である理由は、JIT コンパイラーがループを最適化したからです。それらが計算に役立つものを提供していないことが検出されました。(最初の数値が 2 番目の数値より一貫して速いように見える理由は明らかではありませんが、最適化されたコードが意味のある方法でフィールド アクセスとメソッド アクセスを測定しているとは思えません。)


更新されたコード/結果について: JITコンパイラがまだループを最適化していることは明らかです。

于 2013-02-12T12:04:09.507 に答える