Como definir o tamanho inicial do std :: vector?

130

Eu tenho um vector<CustomClass*>e coloco muitos itens no vetor e preciso de acesso rápido, para não usar a lista. Como definir o tamanho inicial do vetor (por exemplo, 20.000 lugares, para evitar a cópia quando insiro um novo)?

Damir
fonte
1
Existe um construtor e duas funções para isso em qualquer std::vectorreferência, dependendo do que melhor se adapta às suas necessidades.
22412 chris
1
Você não pode evitar a cópia, basta definir o valor inicial.
Juanchopanza
1
Evitar cópias de? O armazenamento de ponteiros é bastante leve em termos de custo para copiar.
user7116
1
@ Damir, você quis dizer std::vectorno título?
Robᵩ

Respostas:

180
std::vector<CustomClass *> whatever(20000);

ou:

std::vector<CustomClass *> whatever;
whatever.reserve(20000);

O primeiro define o tamanho real da matriz - ou seja, torna um vetor de 20.000 ponteiros. O último deixa o vetor vazio, mas reserva espaço para 20000 ponteiros, para que você possa inserir (até) muitos deles sem que seja necessário realocar.

Pelo menos na minha experiência, é bastante incomum que qualquer um deles faça uma enorme diferença no desempenho - mas pode afetar a correção em algumas circunstâncias. Em particular, desde que nenhuma realocação ocorra, é garantido que os iteradores no vetor permanecem válidos. Depois de definir o tamanho / espaço reservado, você garante que não haverá realocações desde que você não t aumentar o tamanho além disso.

Jerry Coffin
fonte
Qual destes seria mais eficiente para um grande número de inserções / exclusões?
12123
3
@ Loggie: Duvido que haja alguma diferença de eficiência. Principalmente, muda a maneira como você o usa - com o primeiro, você apenas endereça os ponteiros, algo como whatever[10000] = somepointer;, onde o último exige que push_backvocê inclua cada ponteiro. Pelo menos se você está acostumado vector, o último é provavelmente mais simples e mais natural.
Jerry Coffin
Se o tamanho do contêiner que está sendo copiado for conhecido, por que não é mais eficiente (re) dimensionar e depois copiar em vez de push_back?
1
@Incinnatus: porque tem uma chamada para reserve, que pré-aloca o tamanho da memória. Em teoria, definir o tamanho ainda pode ser minuciosamente mais rápido, pois também evita o aumento do tamanho atual toda vez que você adiciona um item. Na realidade, duvido que você possa medir isso.
Jerry Coffin
1
na verdade, se você estiver fazendo isso em um caminho quente, e o código for chamado muito, você poderá fazer muitas instruções e economizar tempo.
bayindirh
15

Você precisa usar a função de reserva para definir um tamanho alocado inicial ou fazê-lo no construtor inicial.

vector<CustomClass *> content(20000);

ou

vector<CustomClass *> content;
...
content.reserve(20000);

Quando você reserve()elementos, vectorele alocará espaço suficiente para (pelo menos?) Esse número de elementos. Os elementos não existem no vector, mas a memória está pronta para ser usada. Isso irá acelerar push_back()porque a memória já está alocada.


fonte
Alocar o tamanho também pode ser fornecida durante a construção por passagem em um argumento integrante (por exemplo, std::vector<Custom Class*> content(100);)
adelbertc
@struct: Sim, mas pode ser menos eficiente - por uma quantia muito pequena.