web-dev-qa-db-ja.com

ベクトルのベクトル、予約

intの2次元行列をベクトルのベクトルとして表現したいとします。

std::vector<std::vector<int> > myVec;

内側の次元は一定で、たとえば5で、外側の次元はN以下です。再割り当てを最小限に抑えるために、スペースを予約したいと思います。

myVec.reserve(N);

内部ベクトルにはどのサイズが想定されていますか?これは純粋に実装に依存していますか?これはデータの空間的な局所性にどのように影響しますか?内部次元は定数なので、この定数サイズを使用するようコンパイラーに指示する方法はありますか?内部ベクトルのサイズが変わると、これらの答えはどのように変わりますか?

23
OSE

あなたの内的次元は一定なので、

std::vector< std::array<int, 5> > vecs;
vecs.reserve(N);

これにより、事前割り当てされた連続したストレージが提供され、パフォーマンスに最適です。

15
Ben Voigt

内部ベクトルのサイズは、外部ベクトルのサイズ変更にはまったく関係ありません。ベクトルのバンドルの局所性保証はありません。局所性保証(つまり、メモリ内の連続したブロック)は、単一のベクトルにのみ存在します。

ベクトルオブジェクト自体には定数sizeof- sizeがあり、実際のデータは通常動的に割り当てられることに注意してください。外側のベクトルは、最初の近似で、内側のベクトルへのN個の「ポインター」の連続したブロックです。 reserve呼び出しは、内部ベクトルの可能な要素のためにメモリを予約するのではなく、内部ベクトルオブジェクト自体(つまり、それらの簿記データと動的に割り当てられたデータブロックへのポインター)のためにのみメモリを予約します。

8
us2012

内部ベクトルはデフォルトのコンストラクターで初期化されます。だからあなたが書くなら:

_vector<vector<int> > vecs;
vecs.reserve(10);
_

これは、要素ごとに_vector<int>_またはvector<int>()のコンストラクタを呼び出すことと同じです。つまり、サイズが0のベクトルが作成されます。ただし、ベクターのサイズを変更(予約しない)しない限り、それらを使用することはできません。

また、必要な初期サイズでサイズ変更する方が効率的な場合があることも覚えておいてください。したがって、次のようなことをすると便利です

_vector<vector<int> > vecs(3,vector<int>(5));
_

これにより、サイズ3のベクターが作成され、各要素にはサイズ5のベクターが含まれます。

また、ベクターのサイズを頻繁に変更する場合は、ベクターではなくdequeを使用する方が効率的である可能性があります。要素はメモリ内で隣接していないため、(ベクトルとして)簡単に使用でき、予約する必要はありません。