私のアプリケーションでは、System.Array.Resize をフレームごとに 1 回実行します。最初に、配列を可能な最大サイズに設定してから、サイズを小さくします。かなり小さい場合もあれば、ほんの少し小さい場合もあります。サイズ変更する要素が多いほど、時間がかかるように見えます。おそらく私の観察は間違っているので、ここで質問します。
3 に答える
はい、そうする必要があります。サイズ変更には、新しいメモリを必要なサイズに割り当て、古い配列を新しい配列にコピーすることが含まれます。配列が大きいほど、コピーする量が多くなります。
このメソッドは、指定されたサイズで新しい配列を割り当て、古い配列の要素を新しい配列にコピーしてから、古い配列を新しい配列に置き換えます。
コードについてあまり知らなくても、List<T>
必要なリストとサイズ変更を管理するために を使用してみてください。Unity に提供する必要がある場合は、 を呼び出しますlist.ToArray();
。
これでも配列が作成されてコピーされますが、フレームごとに 1 回だけです。
他の回答が指摘しているように、配列の「サイズ変更」にはすべての要素をコピーする必要があります。これは、N が大きくなった場合の O(N) 操作です。配列のコピーに使用できるアプローチは多数あり、"セットアップ" と "アイテムごと" のコストが異なることに注意してください。小さな配列コピー操作は、一度に 4 バイト (場合によっては、一度に 1 バイト) 処理されますが、より大きな配列操作では、ほとんどのコピーを行うために特別な 16 バイト操作が使用されます。これらの操作は、一度にアラインされた 16 バイトのメモリ チャンクの書き込みに制限されています。コピー元とコピー先のアラインメントに応じて、大規模な配列操作では、4 バイトの 4 つのグループ (最後のバイトが次のグループとオーバーラップする)、16 バイトの多くのグループ、および 4 バイトのさらに 4 つのグループ (ファイルの最初のバイト) のコピーが必要になる場合があります。これは前のグループと重複します)。
配列のサイズ変更の費用を最小限に抑えるための真の鍵は、可能な限りめったに行わないことです。型がその配列のサイズを拡張する必要があるときはいつでもList<T>
、それを 2 倍にします。その配列が 16 項目で始まる場合、配列を 256 要素に倍増する時点で、128 は空になり、64 は 1 回コピーされ、32 は 2 回コピーされ、16 は 3 回コピーされます。一部の要素は最終的に lg(N) 回コピーされますが、サイズ N のリストを構築するプロセスでの要素コピー操作の総数は常に 2N 未満になることに注意してください。
a のバッキング配列に配列としてアクセスする方法はありませんがList<T>
、配列を公開するような方法でクラスを再実装し、配列をパラメーターとして受け入れるすべてのメソッドで指定できるようにするのはかなり簡単です。使用する部分の長さ (単にLength
配列のプロパティにアクセスする代わりに)。
はい。配列のサイズ変更はO(n)操作です。各要素を新しい配列にコピーする必要があります。
たぶん、配列を使用しなかった方が良いでしょうか?アレイは何に使用されますか?アプリケーションに適したより良いデータ構造があるかもしれません。