A maneira mais eficiente de concatenar seqüências de caracteres em JavaScript?

163

Em JavaScript, eu tenho um loop que possui muitas iterações e, em cada iteração, estou criando uma string enorme com muitos +=operadores. Existe uma maneira mais eficiente de criar uma string? Eu estava pensando em criar uma matriz dinâmica na qual continuo adicionando strings a ela e depois faço uma junção. Alguém pode explicar e dar um exemplo da maneira mais rápida de fazer isso?

ómega
fonte
2
Para que você está usando a string? Todas as dicas de desempenho nesta vão variar com base no seu ambiente, os tamanhos de suas cordas, como um motor de js especial otimiza as operações diferentes, etc.
Ben McCormick
1
pode ser duplicado de stackoverflow.com/questions/7299010/…
rab
5
Verifique este link jsperf.com/join-concat/2
rab
Estou usando o IE9, mas está no modo de compatibilidade do IE8 (que não posso alterar). A string enorme é algo que vou inserir no DOM usando jquery.
Omega

Respostas:

135

Parece baseado nos benchmarks do JSPerf que o uso +=é o método mais rápido, embora não necessariamente em todos os navegadores.

Para construir seqüências de caracteres no DOM, parece melhor concatenar a sequência primeiro e depois adicioná-la ao DOM, em vez disso, adicionar iterativamente ao dom. Você deve avaliar seu próprio caso.

(Obrigado @zAlbee pela correção)

Jakub Hampl
fonte
1
Olhe para a página vinculada. Parece que há pouca diferença entre +=e fazer uma junção em uma matriz.
Jakub Hampl 22/05
Parece que adicioná-lo ao DOM para cada string é 66%(para o IE9) mais rápido do que criar uma string e adicioná-la ao DOM.
Omega
a página vinculada usa + = para ambos os testes, sem .join () à vista; portanto, é um teste sem sentido que mostra apenas ruído como qualquer "diferença". um bom exemplo de como js barulhentos podem ser ... o dom é mais lento que a string, então use-o com moderação.
Dandavis
O tempo é apenas um componente. Para rotinas iterativas, pergunto-me qual é o impacto no GC entre os vários métodos?
David Bradley
Para as grandes cadeias, Array.join pode ser preferível devido à concatenação de string é muito desagradável bug de memória bugs.chromium.org/p/v8/issues/detail?id=3175
mwag
70

Não tenho nenhum comentário sobre a concatenação em si, mas gostaria de salientar que a sugestão de @Jakub Hampl:

Para criar seqüências de caracteres no DOM, em alguns casos, pode ser melhor adicionar iterativamente ao DOM, em vez de adicionar uma sequência enorme de uma só vez.

está errado, porque é baseado em um teste defeituoso. Na verdade, esse teste nunca é anexado ao DOM.

Este teste fixo mostra que a criação da string de uma só vez antes da renderização é muito, muito mais rápida. Nem sequer é um concurso.

(Desculpe, esta é uma resposta separada, mas ainda não tenho representante suficiente para comentar as respostas.)

zAlbee
fonte
4
Eu acho que vale a pena ser uma resposta por si só, porque contém um teste e uma conclusão (embora o teste seja baseado / inspirado em outra resposta, isso deve ser bom), sem a necessidade de desculpas.
usar o seguinte comando
14

Três anos atrás, desde que esta pergunta foi respondida, mas vou fornecer a minha resposta mesmo assim :)

Na verdade, a resposta aceita não está totalmente correta. O teste de Jakub usa string codificada, que permite ao mecanismo JS otimizar a execução do código (o V8 do Google é realmente bom nisso!). Mas assim que você usar cadeias completamente aleatórias ( aqui é JSPerf ), a concatenação de cadeias estará em um segundo lugar.

Volodymyr Usarskyy
fonte
Curiosamente, com o Chrome 54 e o Firefox 45 na minha máquina Windows, o concat é mais do que o dobro da velocidade dos outros dois usando sua versão. O IE 11 tem todos os três tão lentos quanto o não-concat nos outros dois navegadores.
ShawnFumo
4
É diferente de versão para versão. Eu acho que, no momento, a VM do Chrome pode conter alguma pré-otimização para este caso. Testei novamente no Chrome v53 e a concatenação agora é a solução mais rápida: D O mesmo hardware, mas uma versão diferente do Chrome fornece resultados totalmente diferentes.
Volodymyr Usarskyy
8

Você também pode fazer concatenação de strings com literais de modelo . Atualizei os testes JSPerf dos outros pôsteres para incluí-lo.

for (var res = '', i = 0; i < data.length; i++) {
  res = `${res}${data[i]}`;
}
Madbreaks
fonte