Estou pré-alocando alguma memória para minha vector
variável de membro. O código abaixo é parte mínima
class A {
vector<string> t_Names;
public:
A () : t_Names(1000) {}
};
Agora, em algum momento, se for t_Names.size()
igual 1000
. Pretendo aumentar o tamanho em 100
. Então, se atingir 1100
, aumente novamente 100
e assim por diante.
Minha pergunta é: o que escolher entre vector::resize()
e vector::reserve()
. Existe alguma escolha melhor nesse tipo de cenário?
Edit : Eu tenho uma espécie de estimativa precisa para o t_Names
. Estimo que seja em torno 700
de 800
. No entanto, em certas situações (raramente), pode crescer mais do que 1000
.
std::vector
.Respostas:
As duas funções fazem coisas muito diferentes!
O
resize()
método (e a passagem do argumento para o construtor é equivalente a isso) inserirá ou excluirá o número apropriado de elementos no vetor para torná-lo determinado tamanho (ele possui um segundo argumento opcional para especificar seu valor). Isso afetará asize()
iteração sobre todos esses elementos, o push_back será inserido depois deles e você poderá acessá-los diretamente usando ooperator[]
.O
reserve()
método apenas aloca memória, mas a deixa não inicializada. Isso afeta apenascapacity()
, massize()
será inalterado. Não há valor para os objetos, porque nada é adicionado ao vetor. Se você inserir os elementos, nenhuma realocação acontecerá, porque foi feita com antecedência, mas esse é o único efeito.Então depende do que você quer. Se você deseja uma matriz de 1000 itens padrão, use
resize()
. Se você deseja uma matriz na qual deseja inserir 1000 itens e evitar algumas alocações, usereserve()
.EDIT: O comentário de Blastfurnace me fez ler a pergunta novamente e perceber que, no seu caso, a resposta correta é não pré-alocar manualmente. Continue inserindo os elementos no final conforme necessário. O vetor será realocado automaticamente conforme necessário e o fará com mais eficiência do que a maneira manual mencionada. O único caso em que
reserve()
faz sentido é quando você tem uma estimativa razoavelmente precisa do tamanho total que precisará facilmente disponível com antecedência.EDIT2: Edição da pergunta do anúncio: se você tiver uma estimativa inicial,
reserve()
essa estimativa. Se isso não for suficiente, deixe o vetor fazer a coisa certa.fonte
vector
.x.reserve(x.size() + newdata); vector<int>::iterator special_element = get_special_element(x); for (int i = 0; i < newdata; ++i) { if some_function(i, special_element) x.push_back(i); }
é bastante robusto no que diz respeito à reserva do espaço. Não tenho idéia de quantos elementos serão realmente adicionados, mas tenho um limite superior. É claro que em caso de dúvida, com vetores, você pode simplesmente usar índices em vez de iteradores, a diferença geralmente é insignificante.size()
. "O método reserve () aloca apenas memória" - ele pode ou não alocar memória, dependendo secapacity()
já é suficiente, também pode precisar mover elementos e desalocar sua memória original. "quer evitar algumas alocações" e copia etc #resize()
não apenas aloca memória, como também cria quantas instâncias quanto o tamanho desejado para o qual você passaresize()
como argumento. Masreserve()
apenas aloca memória, não cria instâncias. Isso é,Saída ( demonstração online ):
Portanto,
resize()
pode não ser desejável, se você não quiser os objetos criados por padrão. Vai ser lento também. Além disso, se você adicionarpush_back()
novos elementos, osize()
vetor aumentará ainda mais alocando nova memória (o que também significa mover os elementos existentes para o espaço de memória recém-alocado). Se você usoureserve()
no início para garantir que já há memória alocada suficiente, osize()
vetor aumentará quando você fizerpush_back()
isso, mas ele não alocará nova memória novamente até que fique sem o espaço reservado para ele .fonte
reserve(N)
, podemos usaroperator []
inofensivamente. correto?reserve
, a especificação requer apenas ele aloca pelo menos que muito, portanto, algumas implementações podem arredondar para algum limite e, portanto, apresentam maior capacidade do que 1000.v.size()
. Observe quereserve(N)
não mudasize()
de vetor.Na sua descrição, parece que você deseja "reservar" o espaço de armazenamento alocado do vetor t_Names.
Observe que
resize
inicialize o vetor recém-alocado ondereserve
apenas aloca, mas não constrói. Portanto, 'reserva' é muito mais rápido que 'redimensionar'Você pode consultar a documentação referente à diferença de redimensionamento e reserva
fonte
reserve quando não desejar que os objetos sejam inicializados quando reservados. Além disso, você pode preferir diferenciar e rastrear logicamente sua contagem versus sua contagem de uso ao redimensionar. portanto, há uma diferença de comportamento na interface - o vetor representará o mesmo número de elementos quando reservado e será 100 elementos maior quando redimensionado no seu cenário.
depende inteiramente de seus objetivos ao combater o comportamento padrão. algumas pessoas preferem alocadores personalizados - mas realmente precisamos de uma idéia melhor do que você está tentando resolver em seu programa para aconselhá-lo bem.
fwiw, muitas implementações de vetores simplesmente dobram a contagem de elementos alocados quando precisam crescer - você está tentando minimizar os tamanhos de alocação de pico ou está tentando reservar espaço suficiente para algum programa sem bloqueio ou algo mais?
fonte
operator[]
nada.