Observando a saída do assembly, o gcc realmente desenrola esse loop no uso dos registradores mmx para despejar em 16 bytes por vez até chegar perto do fim. Eu diria que é muito rápido. A versão do memset pula para o memset, o que eu acho que é tão rápido. Eu usaria seu método.
omniforme
Porém, pular para o memset é uma única instrução, portanto, usá-lo resultará em um tamanho binário menor.
Alexander Shishenko 12/10
2
este não é exatamente o OP pediu, mas simplesmente a reatribuição seu vetor para um novo do mesmo tamanho ( v = std::vector<int>(vec_size,0)) parece um pouco mais rápido do que fillna minha máquina
Yibo Yang
1
Esta é a maneira mais idiomática de fazê-lo, mais idiomática do que usar assign.
AlfC1
1
atribuí-lo a um novo vetor faz alocação de heap? e depois descartar a alocação do vetor existente? Eu pude ver que sendo mais lento que Memset e cols.
Conrad Jones
150
Como sempre, quando você pergunta sobre o mais rápido: meça! Usando os métodos acima (em um Mac usando Clang):
usando 100000 iterações em um vetor de 10000 ints.
Editar: se a alteração desses números altera de maneira plausível os tempos resultantes, você pode ter alguma confiança (não tão boa quanto a inspeção do código de montagem final) de que o benchmark artificial não foi totalmente otimizado. Obviamente, é melhor medir o desempenho em condições reais.
end Editar
+1. Esse benchmark específico não é conclusivo, mas o ponto é absolutamente correto: você deve escrever um teste de desempenho das alternativas, pois elas serão realmente usadas. Se não houver diferença de desempenho, use a fonte mais simples.
21812 Steve Steveop
3
"... não conclusivo ..." Na IMO, essa inconclusividade já é um bom ponto para se fazer benchmarks; na maioria das vezes, o Optimizer já faz um trabalho muito bom para o tipo de situação sobre a qual o OP perguntou. E eu modificar a sua última frase para ler "Se não há significativa diferença de desempenho ..."
Além disso, uau, se você se preocupa com a velocidade sem otimizações (o que pode ser plausível se você estiver implantando no modo 'debug', o que algumas equipes fazem), fillparece terrível. São duas ordens de magnitude mais lentas neste teste.
Kyle Strand
5
@KyleStrand: Não é que o preenchimento seja terrível, é um modelo e o código é gerado com -O0 dentro da sua unidade de tradução. Quando você usa o memset, você está usando o código libc que foi compilado com -O3 (mesmo quando você compila seu código com -O0). Se você se preocupa com a velocidade na depuração e usa modelos, precisará usar instanciação explícita de modelos em um arquivo separado, que você compila com -O3
Como o padrão (2003 TC1) garante que um vetor std :: seja contíguo na memória, isso deve ser bom. Se sua biblioteca c ++ não estiver em conformidade com o TC1 de 2003, não use isso.
Mario
2
@ Mario: Eu não teria postado isso a menos que isso fosse verdade e assumisse ser bem conhecido, é claro. :) Mas obrigado.
desenrole
1
Eu verifiquei a montagem. O ::std::fillmétodo se expande para algo bastante rápido, embora um pouco do lado do código, já que está tudo em linha. Eu ainda o usaria porque é muito melhor ler.
omniforme
4
É melhor adicionar uma verificação se o vetor estiver vazio e não fazer nada nesse caso. Calcular & buf [0] para vetor vazio pode gerar asserções no código STL.
Sergey
4
experimentar
std::fill
e também
std::size siz = vec.size();//no memory allocating
vec.resize(0);
vec.resize(siz,0);
Eu tinha a mesma pergunta, mas bastante curta vector<bool>(depois que o padrão permite implementá-lo internamente de maneira diferente do que apenas uma matriz contínua de elementos booleanos). Por isso, repeti os testes levemente modificados por Fabio Fracassi. Os resultados são os seguintes (tempos, em segundos):
-O0 -O3
----------------
memset 0.6661.045
fill 19.3571.066iterator67.3681.043
assign 17.9750.530for i 22.6101.004
Então, aparentemente, para esses tamanhos, vector<bool>::assign()é mais rápido. O código usado para testes:
Respostas:
fonte
v = std::vector<int>(vec_size,0)
) parece um pouco mais rápido do quefill
na minha máquinaassign
.Como sempre, quando você pergunta sobre o mais rápido: meça! Usando os métodos acima (em um Mac usando Clang):
usando 100000 iterações em um vetor de 10000 ints.
Editar: se a alteração desses números altera de maneira plausível os tempos resultantes, você pode ter alguma confiança (não tão boa quanto a inspeção do código de montagem final) de que o benchmark artificial não foi totalmente otimizado. Obviamente, é melhor medir o desempenho em condições reais. end Editar
para referência o código usado:
Conclusão: use
std::fill
(porque, como outros já disseram que é o mais idiomático)!fonte
assign
é mais lento, exceto por pequenas capacidades em diantelibc++
. CODE coliru / pastefill
parece terrível. São duas ordens de magnitude mais lentas neste teste.E a
assign
função de membro?fonte
Se é apenas um vetor de números inteiros, eu tentaria primeiro:
Não é muito C ++, por isso tenho certeza de que alguém fornecerá a maneira correta de fazer isso. :)
fonte
::std::fill
método se expande para algo bastante rápido, embora um pouco do lado do código, já que está tudo em linha. Eu ainda o usaria porque é muito melhor ler.experimentar
e também
fonte
Eu tinha a mesma pergunta, mas bastante curta
vector<bool>
(depois que o padrão permite implementá-lo internamente de maneira diferente do que apenas uma matriz contínua de elementos booleanos). Por isso, repeti os testes levemente modificados por Fabio Fracassi. Os resultados são os seguintes (tempos, em segundos):Então, aparentemente, para esses tamanhos,
vector<bool>::assign()
é mais rápido. O código usado para testes:Eu usei o compilador GCC 7.2.0 no Ubuntu 17.10. A linha de comando para compilar:
fonte