どちらがパフォーマンスに優れているか、このループ:
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 10; j++) { }
}
またはこのループ:
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 100; j++) { }
}
なぜ?
どちらがパフォーマンスに優れているか、このループ:
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 10; j++) { }
}
またはこのループ:
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 100; j++) { }
}
なぜ?
内側のループが実際に何かを行うと仮定しましょう。FredrikRedin と niculare はもちろん正しいです。内部ループの実行回数は同じです。この場合、2 番目の例は内側のループを 10 回セットアップする必要があるのに対し、最初の例は内側のループを 100 回セットアップする必要があるため、2 番目の例が (わずかに) 優先されます。セットアップされたループの総数:
ループの設定には時間がかかるため、2 番目の例が優先されます。他のすべての条件は同じです (決して同じではありません)。一般に、内側のループと外側のループの間で反復を分割できる場合は、内側のループにより多くの反復を与えて、外側のループの反復回数を減らします。
経験的証拠は、それらがほぼ同じであることを示しています。
(ループ内の最小限の操作でのミリ秒単位の時間)
最初の1003、2番目の1113
最初の1012、2番目の1001
最初の1000、2番目の1002
最初の1001、2番目の1006
最初の1013、2番目の1001
最初の1001、2番目の1001
最初の1007、2番目の1027
最初の1018、2番目の1001
最初の1001、2番目の1002
最初の1001、2番目の1001
最初の1001、2番目の1001
最初の1002、2番目の1000
理論的には、私はangelatlargeの答えを使用します。私はそれがループの中にあるものに依存すると信じています:あなたが新しいオブジェクトなどを構築しているなら、何百回も何十回よりも遅くなります。
'*'は可換であるため、実際には同じ回数の反復を実行します。前者の場合、反復回数はになりますが、後者の100*10
場合はになります10*100
。したがって、両方とも1000回の反復に再開します。
その同じ数の操作。反復や2つのforループ(中断/続行)のいずれかをスキップするロジックがない限り、なぜパフォーマンスの違いを期待するのですか?
javac コンパイラ (Java コードをバイトコードにコンパイルする) と JIT (バイトコードをアセンブリにコンパイルする) の両方で、両方のループをノーオペレーションとして扱うことができます (ループ本体に何もないため)。
実際には、javac がそれを行う可能性は低いですが、JIT がそのコードをスキップする可能性は非常に高いです。
結論: Java コードのパフォーマンスはコンテキストに大きく依存し、何もしないループに関する特定の質問については、答えは次のとおりです。どちらもスキップされ、すぐに実行されます。
それらは同じですが、最初の反復子に 100 のサブ反復子が含まれており、次の反復子の変更は 10 ステップであり、100 ステップよりも優れているため、原子時間では 10*100 の方が優れています。最良の結果を得るにはAtomic Integer
、 またはbyte
を使用できますint
。
int
32 ビットとbyte
8 ビットです。
同じ性能とは思えません。その理由は分岐予測です。