[最適化マニアクス]ヒープメモリを使わない超省メモリ配列

JacksonDunstan.com
JacksonDunstan.com covers C# programming for Unity

ゲームを作る上で配列やListは欠かせません。しかしclass型であるためヒープメモリに確保され、GCの対象となってしまいます。

しかしこのSmallBufferはstruct型のためスタックメモリから確保され、GCの対象となりません。素晴らしい!!(もちろんclassのメンバ変数として定義した場合はヒープメモリにのります。

スポンサーリンク

使いどころ

関数の戻り値

処理の結果として配列を戻したいケースがあります。都度newしてしまうとメモリの無駄づかいになってしまいます。メンバ変数にList形式で確保しておき使いまわす方法もありますが、参照型であるためどこかで書き換わる危険性があります。また可読性もよくないです。

ヒープメモリにのらないSmallBufferであれば、メモリ消費の問題や参照型の危険性に悩むことなく安全に戻り値として使えます。

メンバ変数

ターン制バトルにおける敵味方配列のように、要素数がそれほど多くない固定長配列がほしいケースが多々あります。Listや配列の場合、class特有のオーバーヘッドがありメモリ消費を抑えたい場面で使用をためらうことがあります。

Struct型であるSmallBufferであればオーバーヘッドがないため、最適化を推し進めることができます。

デメリット

コードサイズ肥大化

コード自動生成型であるため、いろんな型を生成するとその分コードサイズが大きくなります。アプリサイズや常駐メモリ使用量を抑えたいときは注意が必要です。

要素数が多いのには不向き

struct型であるSmallBufferではスタックメモリに大量に確保します。関数の引数や戻り値として値渡ししてしまうとそのたびにスタックメモリ確保が発生し処理落ちの原因になりかねません。逆に要素数が多い場合は、classのオーバーヘッドは無視できるでしょう。

まとめ

うまく使えばパフォーマンスと可読性の両立できます。積極的に取り込んでいきましょう