web-dev-qa-db-ja.com

std :: vector resize(0)またはclear()-ただし、容量を維持

多くのオブジェクトをレンダーデータ(メッシュ)を含む単一のベクトルにマージしています。このベクトルは、フレームごとに(ほぼ)クリアされ、補充されます。

問題は、clear()も容量を変更する可能性があるため、ベクターサイズをクリアしてから再度予約すると、私の場合、パフォーマンスに大きな影響を与えることです。

つまり、ベクターの容量がいつ変更されるかを制御する必要があります。私はそれを変更する時だと自分が決めるまで、かなり長い間古い容量を保持したいと思います。

2つのオプションが表示されます。

  • _std::vector_の容量がいつ変化するかを制御する方法を理解する
  • 必要なサイズ以下の大きなデータオブジェクトをフェッチし、必要に応じて再利用/解放する、大きなメモリオブジェクトのメモリプールを実装します。

更新

さらに、たとえばresize(10)が呼び出され、後でresize(5)が呼び出された場合はどうでしょう(例として、実際の数に数百万を掛けます)。

後でresize(5)を呼び出すと、ベクトルが再割り当てされる可能性がありますか?

9
benjist

実際、clearメンバー関数は、ベクトル容量を変更せずに保持します。これは、各ベクトル要素を破棄(デストラクタを呼び出し)し、ベクトルサイズを0に設定するだけです。

この状況では、各反復でclear()を呼び出してすべてのベクトル要素を破棄し、次にメンバー関数reserve(size)を呼び出します。これは、ベクトル容量が小さすぎる場合、少なくともsizeに増加します。

10
Oliv

このベクトルは、フレームごとに(ほぼ)クリアされ、補充されます。

別のアプローチをお勧めします。

レンダリングデータのバッファとして機能するクラスを作成します。

私が間違っていなければ、バッファの容量を減らすことは決してありません。必要なときにのみ容量を増やします。

クラスが実装の詳細であり、インスタンスのみが構築されることを確認してください。

これが私が考えていることの骨格的な実装です。

namespace Impl_Detail
{
   struct Buffer
   {
      size_t capacity;
      size_t size;
      std::vector<char> data;

      // Pick whatever default capacity makes sense for your need.
      Buffer(size_t cap = 100) : capacity_(cap), size_(0), data(cap) {}

      void ensureCapacity(size_t cap)
      {
         if ( capacity_ < cap )
         {
            capacity_ = cap;
            data.resize(capacity_);
         }
      }


      // Add any other helpful member functions as needed.
   };

   // Create an instance and use it in the implementation.
   Buffer theBuffer;
}
2
R Sahu