3

コードのテストを開始する前に、パフォーマンス テスト スイートの一部として単純な単体テストを使用して、ベース システムが正常で動作することを確認します。通常、この方法でマシンが実際のパフォーマンス テストの実行に適していることを確認します。

このテストを使用して Java 6 と Java 7 を比較すると、Java 7 の実行時間がかなり長くなります。Java 6 では平均 22 秒、Java 7 では 24 秒です。テストはフィボナッチのみを計算するため、ここでは単一スレッドでのバイトコード実行のみが関連し、I/O などは関連しません。

現在、「-server」の有無にかかわらず、32ビットと64ビットの両方のJVMを使用して、Windowsでデフォルト設定で実行しています。すべての実行は、Java 7で同様の低下を示しています。

Java 7 と Java 6 を一致させるには、どのチューニング オプションが適しているでしょうか?

public class BaseLinePerformance {

    @Before
    public void setup() throws Exception{
        fib(46);
    }

    @Test
    public void testBaseLine() throws Exception {
        long start = System.currentTimeMillis();
        fib(46);
        fib(46);
        System.out.println("Time: " + (System.currentTimeMillis() - start));
    }

    public static void fib(final int n) throws Exception {
        for (int i = 0; i < n; i++) {
            System.out.println("fib(" + i + ") = " + fib2(i));
        }
    }

    public static int fib2(final int n) {
        if (n == 0)
            return 0;
        else if (n == 1)
            return 1;
        else
            return fib2(n - 2) + fib2(n - 1);
    }
}

更新:スリープを行わないようにテストを縮小し、How do I write a correct micro-benchmark in Java?の他の提案に従いました。、Java 7 と Java 6 の間にも同じ違いが見られます。コンパイルと GC を出力するための追加の JVM オプションは、実際のテスト中に出力を表示せず、最初のコンパイル情報のみが出力されます。

4

2 に答える 2

5

私の同僚の 1 人は、もう少し掘り下げた後、この理由を発見しました。

JVM フラグ -XX:MaxRecursiveInlineLevel があり、デフォルト値は 1 です。以前のバージョンでは、この設定の処理が少し間違っていたようです。そのため、Sun/Oracle は Java 7 でこれを「修正」しましたが、副作用があります。インライン化があまり積極的に行われないことがあるため、再帰コードの純粋なランタイム/CPU 時間が以前より長くなる可能性があります。

少なくとも問題のテストでは、Java 6 と同じ動作を得るために、2 に設定してテストしています。

于 2013-09-10T14:52:04.483 に答える
0

これは簡単な答えではありません。この 2 秒を説明できる要因はたくさんあります。

あなたのコメントは、マイクロ ベンチマークに既に精通しており、コードが最適化された JIT 状態に達し、GC が発生しないように JVM をウォームアップした後にベンチマークが実行され、ハードウェアの設定が変更されていないことを前提としています。

ベンチマークの CPU プロファイリングをお勧めします。これにより、この 2 秒がどこで考慮されているかを特定し、それに応じて行動することができます。

バイトコードに興味がある場合は、それをのぞいてみることができます。

これを行うには、クラスをコンパイルし、両方のマシンで javap -c ClassName を実行します。これにより、クラス ファイルのバイトコードが逆アセンブルされて表示されます。ここでは、コンパイルされた両方のクラス間の変更が確実に表示されます。

結論として、データを見てから 22 秒に達するように、それに応じてアプリケーションをプロファイリングおよび調整します。バイトコードの実装に関してできることは何もありません。

于 2013-09-04T05:40:48.133 に答える