2017-02-11 5 views
1

Stack Overflowに関する似たようなトピックを読んだ後、次のコードを書いて、一貫性のある方法について考えてみましょう。System.nanoTime()最初のメソッド呼び出しが常に最も長くかかるのはなぜですか?

空のvoid関数へのメソッド呼び出しの前後で、処理の経過時間を記録するだけでSystem.nanoTime()を呼び出します。しかし、結果でわかるように、最初の呼び出しは常に最長です。これの理由は何ですか?

public class Test { 
    public static void main(String[] args) { 
     for(int i = 0; i < 10; i++) { 
      double start = System.nanoTime(); 
      foo(); 
      double end = System.nanoTime(); 
      double diff = end - start; 
      System.out.println("Diff: " + diff); 
     } 
    } 

    public static void foo() { 

    } 
} 

結果:私はこの質問を読んでなかった

Diff: 2765.0 
Diff: 509.0 
Diff: 236.0 
Diff: 238.0 
Diff: 230.0 
Diff: 539.0 
Diff: 359.0 
Diff: 356.0 
Diff: 380.0 
Diff: 353.0 

注:またWhy does first call to java.io.File.createTempFile(String,String,File) take 5 seconds on Citrix?

、このリンクは、今後の参考のために有用であるが、必ずしも私の具体的な質問に答えていません。How do I write a correct micro-benchmark in Java?

+1

単語:「キャッシュ」(すべての種類のレイヤー)。キャッシュが関わるとすぐに、同じことを2回目に行う方がはるかに高速です。また、2マイクロ秒の違いは実際には何の問題もなく、なぜnanoTimeを浮動小数点数に変換するのですか? – Thilo

+0

そのメソッドは本当に空ですか?たぶん、JVMがそれを明らかにし、それを完全に最適化するのだろうか? 2つのフォローアップをしてください:a)コード間でメソッド呼び出しを全くしないでnanoTime diffを測定します。b)fooメソッドで小さな計算を行います。 – Thilo

+0

[JITコンパイラ](http://stackoverflow.com/questions/95635/what-does-a-just-in-time-jit-compiler-do)を使用すると、コードはしばらくの間、コードが実行された後に動作します。これらを実行する適切な方法は、[jmh](http://openjdk.java.net/projects/code-tools/jmh/) –

答えて

3

JVMは、クラス解決(JVMS 5.4.3参照)を遅延して実行します。あなたの場合、定数プール内のfooへのシンボリックリファレンスは、invokestaticバイトコードの最初の実行時に、つまりメソッドの最初の呼び出し時に解決されます。明らかに、すでに解決済みのバイトコードを実行するだけでは時間がかかります。

関連する問題