2011-09-01 2 views
6

私はJavaで自動ボクシングとアンボクシングの速度をテストしようとしていますが、それをプリミティブの空のループと比較しようとすると、興味があることに気付きました。このスニペット:Java:空のループはどのくらいの時間使用されますか?

for (int j = 0; j < 10; j++) { 
    long t = System.currentTimeMillis(); 
    for (int i = 0; i < 10000000; i++) 
     ; 
    t = System.currentTimeMillis() - t; 
    System.out.print(t + " "); 
} 

私はこれを実行するたびに、それは同じ結果を返します:なぜ、最初の二つのループは常にある程度の時間がかかるん

6 7 0 0 0 0 0 0 0 0

、そして残りはちょうどスキップされているように見えますシステムによって?

In this answer to this post,ジャストインタイムのコンパイルでこれを最適化できると言われています。しかし、もしそうなら、なぜ最初の2つのループはまだ時間がかかりましたか?

+3

このテストでは、System.nanoTime()がより多く指定されていると思われます。クライアント/サーバのVMでも若干の違いがあります。 –

+0

ちょうど、ミリ秒は粗すぎます。 –

答えて

20

特定のコードが何度も実行された後にJITトリガーが発生します。

HotSpot JVMは、コード内の「ホットスポット」を特定しようとします。ホットスポットは、何度も実行されるコードの一部です。これを行うために、JVMはさまざまな命令の実行を「カウント」し、あるピースが頻繁に実行されると判断すると、JITをトリガーします。 (これは近似ですが、このように説明するのは簡単です)。

JIT(Just-In-Time)は、そのコードを取り込み、より高速にしようとします。より速くあなたのコードの実行を行うためにJITが使用する

技術はたくさんありますが、最も一般的に混乱を作成し、1は、次のとおりです。

  1. それはコードのその部分である変数を使用するかどうかを決定しようとしますそれ以外の場所(無駄な変数)では使用されず、それらを削除します。
  2. 同じロックを複数回取得して解放すると(同じオブジェクトの同期メソッドを呼び出す場合など)、ロックを1回取得して、すべての呼び出しを1つの同期ブロックで実行することができます。
  3. オブジェクトのメンバーそれは揮発性であると宣言されていないので、それを最適化して(レジスタなどに値を置く)、マルチスレッドコードで奇妙な結果を作り出すことができます。
  4. コールのコストを避けるため、インラインメソッドを使用します。
  5. バイトコードをマシンコードに変換します。
  6. ループがまったく役に立たない場合は、完全に削除することができます。

だから、あなたの質問に適切な答えは空のループは、JITedされた後、実行には時間を要しません。..おそらく、もはや存在しないということです。

また、他にも多くの最適化がありますが、私の経験では、これはほとんどの頭痛を引き起こしたものの1つです。

また、Javaの新しいバージョンではJITが改善されていますが、プラットフォームによっては若干異なる場合もあります(特定のプラットフォーム固有のものであるため)。最近のJavaのバージョンでは、これらの最適化の一部がコンパイラに直接移されたとしても、通常はjavapを使用してバイトコードを調べることはできないため、JITで行われる最適化は理解しにくいです(たとえばJava 6以降ではコンパイラは未使用のローカル変数とプライベートメソッドを検出して警告することができます)。

何かをテストするためにいくつかのループを書いているのであれば、ループをメソッドの中に入れて、それを計る前に数回呼び出すことをお勧めします。時限ループ。

これは、実際にトリガされる保証(または特定のプラットフォームに存在することさえある)がない場合でも、通常、JITをあなたのような単純なプログラムで起動します。

JITまたは非JITのタイミング(私がやったこと)についての妄想を取りたい場合:最初のラウンドを行い、ループの各実行をタイミングし、タイミングが安定するまで待ちます(たとえば、 %)、あなたの "本当の"タイミングから始めてください。

7

JITは、そうすることに何らかの利点があると判断するまで、コードの塊をキックしません。つまり、コードの最初の数回はJITされません。

+0

ありがとう!わかりますが、空のループは何をすることができますか? @Simone Gianniが言っているように、ループがしばらく実行されていないと、JIT(保証されている)は起動されません。編集:再びありがとう!私はSimoneの答えから答えを得た:) –

関連する問題