2

私は 2 つのコードを持っています。実行時にどちらが速いのか、なぜ速いのかを知りたいです。JVM と CPU についてはあまり学びませんが、熱心に取り組んでいます。すべてのヒントが役立ちます。

int[] a=new int[1000];
int[] b=new int[10000000];
long start = System.currentTimeMillis();
//method 1
for(int i=0;i<1000;i++){
    for(int j=0;j<10000000;j++){
        a[i]++;
    }
}
long end = System.currentTimeMillis();
System.out.println(end-start);

start=System.currentTimeMillis();
//method 2
for(int i=0 ;i<10000000;i++){
    for(int j=0;j<1000;j++){
        b[i]++;
    }
}
end = System.currentTimeMillis();
System.out.println(end-start);
4

8 に答える 8

5

理論的にはまったく同じですが、実際には小さな違いがありますが、無視できるほどの違いがあります。実際、小さすぎて本当に重要ではありません。

基本的な考え方は、配列bがメモリに格納される方法です。それははるかに大きいため、プラットフォーム/実装によっては、チャンク、つまり非連続に保存される場合があります。これは、1000 万の整数の配列が 4000 万バイト = 40 MB であるためです。

編集:それぞれ572と593を取得します。

于 2013-09-27T07:33:15.487 に答える
0

現代のアーキテクチャは複雑であるため、この種の質問に答えることは決して容易ではありません。

実行時間は同じか、最初の方が速い可能性があります。

この場合に考慮すべきことは、主にメモリ アクセスと最適化です。

優れたオプティマイザは、値が読み取られないことを認識するため、ループを完全にスキップできます。これにより、どちらの場合も実行時間が 0 になります。このような最適化は、コンパイル時または実行時に行うことができます。

最適化されていない場合は、考慮すべきメモリ アクセスがあります。a[]よりもはるかに小さいため、より高速なキャッシュ メモリに容易に収まり、キャッシュ ミスb[]が少なくなります。

考慮すべきもう 1 つのことは、メモリ インターリーブです。

于 2013-09-27T08:39:57.110 に答える
0

最初はより騒々しくなります。最初aiセルの初期化により、回数がはるかに少なくなります。

于 2013-09-27T07:37:16.710 に答える
0

私の推測では、どちらもほとんど同じです。そのうちの 1 つは処理する配列が小さいですが、メモリの初期割り当てを除いて大きな違いはありません。これはとにかく測定範囲外です。

各反復を実行する時間は同じでなければなりません (値を配列に書き込みます)。大きい数値をインクリメントしても、小さい数値をインクリメントするよりも JVM に時間がかかるべきではありません。

しかし、自分自身を測定する方法をすでに知っているのに、なぜ質問するのでしょうか?

于 2013-09-27T07:27:16.317 に答える
0

big-oh表記をチェック

ネストされた for ループは O(n^2) です - 理論的には同じように実行されます。

数値 1000 または 100000 は定数 k O(n^2 + k) です

他にもさまざまな要因があるため、実際にはまったく同じではありませんが、ほぼ同じです。

于 2013-09-27T07:27:26.267 に答える
0

a には値 10000 の 1000 エントリが含まれ、b には値 1000 の 10000000 エントリが含まれるため、結果は明らかに異なります。あなたの質問はよくわかりません。エンドスタートの結果は?JVM が forloops を最適化する可能性があります。JVM が配列内の最終結果がどうなるかを理解している場合、最小の配列よりもはるかに簡単に計算できます。なぜなら、それは 1000 回の割り当てしか必要としないのに対し、もう一方の割り当ては 10 000 倍必要だからです。 .

于 2013-09-27T07:27:49.290 に答える