5

奇妙な結果に出くわしたとき、私はオブジェクトの割り当てに関していくつかのパフォーマンステストを行っていました。私は次のJavaコードを持っています:

public static long TestMethod(){
    int len = 10000000;
    Object[] obs = new Object[len];
    long t = System.nanoTime();
    for (int i = 0; i < len; i++) {
        obs[i] = new Object();
    }
    return System.nanoTime() - t;
}

public static void main(String... args) throws InterruptedException {
    for(int i = 0; i < 10; i++){
        System.gc();
        System.gc();//Wait for the gc to be finished
        Thread.sleep(1000);
        System.out.println(TestMethod());
    }
}

期待:オペレーティングシステムとホットスポットの拡張機能からより大きなメモリスペースを要求するため、最初の呼び出しは2番目の呼び出しよりも遅くなります。しかし、2番目と3番目はほぼ同じになります。

観測結果

11284734000
799837000
682304000
304736000
380770000
392786000
374279000
381611000
379174000
407256000

それでも、3回目と4回目の反復の間でかなりのスピードアップがあります。このスピードアップの原因は何ですか?他の関数をテストするときに測定値が正確であることを確認するにはどうすればよいですか?測定する前に関数を4回以上呼び出す必要がありますか?

4

2 に答える 2

4

このスピードアップの原因は何ですか?

これはおそらくJITコンパイルですが、コードのロードやヒープのウォームアップ効果によるものである可能性もあります。

他の関数をテストするときに測定値が正確であることを確認するにはどうすればよいですか?測定する前に関数を4回以上呼び出す必要がありますか?

あなたはそのようなことをする必要があります。測定からJVMウォームアップの影響を排除し、それでも代表的な結果を得る方法は他にありません。Javaの有効な「マイクロベンチマーク」を作成することは困難であり、試す前にすべての問題を確認する必要があります。これから始めましょう:Javaで正しいマイクロベンチマークを書くにはどうすればよいですか?


他にもいくつか注意しておきます。

  1. 測定からガベージコレクションのコストを削除する試みは失敗したようです(私はそれがあなたが行っているように見えることだと思います。の実行中にマイナーコレクションを取得しているようですtestMethod。これは、「定常状態」の結果の最大7%の変動を説明します。

  2. オブジェクトを割り当てるコストと解放するコストを分離すると、誤解を招く結果が生じる可能性があります。オブジェクトを割り当てるための「合計」コストには、リサイクル時にメモリをゼロにするコストが含まれます...これはガベージコレクタによって行われます。

  3. 実際、最も有用な指標は、割り当て/収集サイクルのオブジェクトごとの償却コストです。そして、それは(驚くべきことに)GCが実行されたときの非ガベージの量に依存します...これはベンチマークが考慮していないことです。

于 2012-12-30T20:58:59.363 に答える
2

あなたが述べたように、関数の実行を高速化できる要因は複数あります。

  • 何よりも、 JITはアプリケーション中のさまざまな段階または瞬間に発生する可能性があります (これが、JVM にウォームアップのための十分な時間を与えずにプロファイリングを行うと、誤解を招く結果につながる可能性がある理由です)。
  • OSへのメモリ要求
  • 割り当てているオブジェクトのヒープ上のメモリの再利用

すべてのステップがいつ発生するかを確認することはできず、コードの断片がいつネイティブ コードにコンパイルされるかを知ることはできませんが、これが最初の呼び出しの直前に発生すると仮定するのは正しくありません。 4回目の繰り返しか何か。残念ながら、これらの詳細は JVM 実装内に隠されています。

于 2012-12-30T20:47:55.267 に答える