std::vectorとstd::listは、実装や動作が異なるSTLの異なるコンテナです。
選び方:
std::vectorを使用するべきです。std::listは、大量のデータを扱う際に任意の位置での挿入/削除が必要な場合のみ正当化されます。この場合、vectorの要素を移動するのが非常に高コストです。std::vectorがしばしば速いです。例:
std::vector<int> v; v.push_back(1); v[0] = 2; // インデックスによる高速アクセス std::list<int> l; l.push_back(1); // l[0] = 2; // エラー: std::listにはインデックスアクセスがありません!
"非常に頻繁にコレクションの中央に挿入する場合でも、なぜ現代のC++プロジェクトでstd::listがほとんど使用されないのでしょうか?"
答え:
実際には、小さなアロケーションの多さ、データの局所性の損失(キャッシュフレンドリーでない)、構造の冗長性、一部の操作のサポートの悪さ(std::listは、大きなリストであってもアロケーションとデアロケーションにかかる時間の損失により非効率です。キャッシュのスキップによる遅延は、しばしば漸近的利益を上回ります)。さらに、現代のプロセッサはキャッシュローカリティに非常に敏感なので、大量のデータがある場合でもstd::vectorは実際にはしばしば速いのです。
物語
リアルタイムシステムで、イベントキューの保存に std::list を選択しました。結果、システムは頻繁なヒープアクセスのために10倍遅くなりました。
物語
グラフィックスプロセッサで、隣接リストを挿入のために std::list 形式で保存しました。これにより、メモリ使用量が劇的に増加し、L1/L2キャッシュが劣化しましたが、速度の実際の利益は得られませんでした。
物語
レポート生成サービスで、各レポートはLinked Listオブジェクトから集められました。ストレステストでサービスが「遅く」なり、プロファイリングでリストの操作によるアロケーションコストにボトルネックがあることが示されました。vectorに移行した結果、改善されました。