2011-12-18 12 views
0

Javaで高速なものはどれですか?Javaでのループの混乱

a) for(int i = 100000; i > 0; i--) {} 
b) for(int i = 1; i < 100001; i++) {} 

私はオプションaである解答を探していましたか?任意のヘルプが評価されます

+0

留守番はありません、かなり簡単なはず? (ただし、副作用がないので、JVMはそれを最適化するかもしれません) –

+0

"A"は "B"よりもはるかに速いと言っていますか? –

+0

いくつかのロジックがありますが、 – sum2000

答えて

7

逆ループがJavaで少し速くなる場合があります。ここに例を示すbenchmarkがあります。典型的には、その違いは、基礎となるプロセッサアーキテクチャのコンテキストの両方で、増分/減分命令またはループ終了比較命令の実装の詳細によって説明されます。より複雑な例では、ループを逆にすることで依存関係を取り除き、他の最適化を有効にしたり、メモリの局所性やキャッシング、ガベージコレクションの動作を改善することができます。

いずれのループも常に高速であると想定することはできません。具体的なケースでは、特定のプラットフォームでどれが優れているかを判断するためにベンチマークが必要です。そして、私はJITコンパイラがこれと何をしなければならないか考慮していません。

とにかく、パフォーマンスを大幅に向上させることなく、コードを読みにくくするマイクロ最適化の一種です。厳密に必要な場合を除いて避けてください。「時期尚早の最適化はすべての悪の根源です。

+2

予想通り、アレイの最後のビットがキャッシュに残っているため、ベンチマークが高速化するだけです。 /特に、1,000万回と1,500万回の走行の両方が、前進と後退の間の正確に同じ(31ms)時間差を有するわけではない。 –

+1

"時期尚早の最適化はすべての悪の根源です"は再び引用する価値があります** **! – dantuch

+0

@ TomHawtin-tacklineどのアレイですか? – harold

2

ちょうど私の帽子から話をしていますが、アセンブリ言語は登録された値の比較よりもサイクル数が少ないゼロとの特定の比較を持っていることが分かります。

+0

通常、減分命令はフラグを設定できるため、比較命令は必要ありません。また、値を比較する必要がありますが、これは短いループのレジスタに配置される可能性があります(長いループでは重要ではありません)。 –

0

答えはそうだと思います。私は答えを思いつきます。つまり、Java仮想マシンは、比較をより速くゼロで「翻訳」します。

1

一般的に、Oracle HotSpotは実際のコードでの最適化に重点を置いています。つまり、フォワード・ループの最適化はバックワード・ループよりも実装される可能性が高くなります。マシンコードの観点からは、デクリメントループは命令を保存することがありますが、特にメモリアクセスが頻繁に行われている場合は、パフォーマンスに大きな影響を与える可能性は低いです。現代のCPUは、フォワードとして遡って幸せになれば幸いだと理解しています(歴史的にフォワードアクセスのために最適化された時代がありました)。特定のストライドアクセスパターンを最適化することさえできます。 「高速である」

(また、ホットスポット(少なくともサーバー/ C2味)空のループを除去することが可能である。)