一般に、メモリ使用量に関しては、侵入型コレクションが最も効率的です。あなたの目標が最後のすべての CPU サイクルを圧迫することである場合、それが唯一の方法です。
ブースト共有ポインターのリストを考えてみましょう。新しいオブジェクトを作成すると、次のことが起こります。
- ヒープから割り当てられ、初期化されたオブジェクト
- 生のポインターから共有ポインターをブーストするコンストラクターは、ヒープ上に別のオブジェクトを割り当てて、オブジェクトの参照カウンターを格納します (参照カウンターがこの割り当てを回避してオブジェクトに格納されるため、侵入ポインターをブーストする方が優れているのはこのためです)。
- list::insert はリスト ノードを割り当て、共有ポインタをコピーします
上記では、新しいオブジェクトを作成してコレクションに挿入するために、3 つのメモリ割り当てが必要です。
ここで、侵入型リストの使用を検討してください。同じタスクの場合、次のようになります。
- 新しいオブジェクトが割り当てられ、初期化されます
- list::insert は、ノードがオブジェクトに埋め込まれており、既に割り当てられているため、オブジェクトのリスト ノード ポインターに割り当てるだけです。
ここでは、メモリ割り当てが 1 回だけ発生します。侵入型コレクションを使用すると、CPU がアドレス指定するメモリが少なくなるため、CPU キャッシュの使用率が向上し、キャッシュ ミスが少なくなり、メモリ フットプリントが減少します (参照の局所性原則として知られています)。
侵入型コレクションの欠点は、オブジェクトが一度に要素になることができるコレクションのタイプとコレクションの数を事前に把握しておく必要があることです。私の個人的な経験では、この余分な事前の考え方は、よりクリーンでシンプルなデザインにつながります。