たとえば、完全な int[50][8] は、8 つの完全な int[50] 配列よりも多くのリソース (RAM と CPU) を使用しますか?
6 に答える
最初のケースでは、8つのintを保持する50個の配列オブジェクトを指す1つの配列オブジェクトがあります。したがって、1+50の配列オブジェクト+最初の配列オブジェクトの50のポインタ。
2番目のケースでは、50個のintを保持する8個の配列オブジェクトを指す1個の配列オブジェクトがあります。したがって、1+8個の配列オブジェクト+最初の配列オブジェクト内の8個のポインター。intを保持することは洗浄です。
このためのCPU使用率を評価する良い方法はありません。
ここで比較することが3つあるようです。
new int[50][8]
new int[8][50]
new int[400]
今、私はこれを混乱させますが、覚えておく方法は、new int[50][]
どちらが有効かを考えることです。
サイズnew int[50][8]
8の50個の配列(51個のオブジェクト)も同様です。new int[8][50]
サイズ50の8つの配列(9つのオブジェクト)の配列です。9つのオブジェクトのオーバーヘッドは51よりも低くなります。これnew int[400]
は1つのオブジェクトにすぎません。
ただし、このサイズでは、プログラムのパフォーマンスに測定可能な違いはおそらくありません。配列をオブジェクト内にカプセル化して、実装を変更し、クライアントコードへのより自然なインターフェイスを提供できるようにすることができます。
1 つの追加の使用ポイント (残念ながら現在は見つけることができませんが、かなり常識的な参照から来ました)-
この論文の著者は、スパース配列を多次元配列に圧縮するさまざまな方法をテストしていました。彼らが気づいたことの 1 つは、反復する方法によって速度が異なるということです。
int[i][j] がある場合は、実行する方が速いという考えでした
for (i) {
for (j)
するよりも
for (j) {
for (i)
最初のインスタンスでは、連続して格納された要素を反復処理しているためです。
int[50][8] は長さ 8 の 50 個の配列です int[8][50] は長さ 50 の 8 個の配列です int[400] は 1 つの配列 400 です。各配列には約 16 バイトのオーバーヘッドがあります。
ただし、ここにあるサイズについては、実際には問題ではありません。どちらにしてもあまり節約できません。
int[] myInt = int[400] 配列を使用し、myInt[x+y*50] を使用して位置 (x,y) の int に手動でアクセスすることで、少量のメモリを微調整できます。これにより、50 32-記憶の断片。そのようにアクセスすると、(hotspot コンパイラがこれに対して何をするかを正確に知っている人は..) 乗算のためにもう 1 つの命令が必要になる可能性があります。
この種のマイクロ最適化では、アプリのパフォーマンスが向上することはほとんどなく、可読性が低下します。
実際の違いを確認するために、非常に大きな配列を使用して小さなパフォーマンス テストを作成することをお勧めします。実際には、これが少しの違いを生むとは思いません。