Hoje, eu li este tópico sobre a velocidade da concatenação de strings.
Surpreendentemente, a concatenação de strings foi a vencedora:
O resultado foi contrário ao que eu pensava. Além disso, existem muitos artigos sobre este que explicam oposta como este .
Posso supor que os navegadores são otimizados para sequenciar concat
na versão mais recente, mas como eles fazem isso? Podemos dizer que é melhor usar +
ao concatenar strings?
Atualizar
Portanto, em navegadores modernos, a concatenação de strings é otimizada, portanto, usar +
sinais é mais rápido do que join
quando você deseja concatenar strings.
Mas @Arthur apontou que join
é mais rápido se você realmente quiser juntar strings com um separador.
Atualização - 2020
Chrome: Array join
quase 2 times faster
é String concat +
Consulte: https://stackoverflow.com/a/54970240/984471
Como nota:
- Array
join
é melhor se você tiverlarge strings
- Se precisarmos gerar
several small strings
na saída final, é melhor ir com string concat+
, caso contrário, ir com Array precisará de várias conversões de Array para String no final, o que é uma sobrecarga de desempenho.
fonte
Respostas:
O mecanismo javascript V8 (usado no Google Chrome) usa este código para fazer concatenação de strings:
Então, internamente eles o otimizam criando um InternalArray (a
parts
variável), que é então preenchido. A função StringBuilderConcat é chamada com essas partes. É rápido porque a função StringBuilderConcat é um código C ++ altamente otimizado. É muito longo para citar aqui, mas procure no arquivo runtime.cc paraRUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat)
ver o código.fonte
arr.join vs str+
no cromo você obtém (em operações por segundo)25k/s vs 52k/s
. no Firefox novo você começa76k/s vs 212k/s
. entãostr+
é MAIS RÁPIDO. mas vamos dar uma olhada em outros navegadores. O Opera oferece 43k / s contra 26k / s. IE dá1300/s vs 1002/s
. veja o que acontece? o único navegador que precisa de otimização seria melhor usar o que é mais lento em todos os outros, onde isso não importa em nada. Portanto, nenhum desses artigos entende nada sobre desempenho.O Firefox é rápido porque usa algo chamado Ropes ( Ropes: an Alternative to Strings ). Uma corda é basicamente apenas um DAG, onde cada Nó é uma corda.
Então, por exemplo, se você fizer isso
a = 'abc'.concat('def')
, o objeto recém-criado terá esta aparência. Claro que não é exatamente assim que parece na memória, porque você ainda precisa ter um campo para o tipo de string, comprimento e talvez outro.E
b = a.concat('123')
Portanto, no caso mais simples, a VM quase não precisa fazer nenhum trabalho. O único problema é que isso retarda um pouco outras operações na string resultante. Isso também reduz a sobrecarga de memória.
Por outro lado
['abc', 'def'].join('')
, normalmente apenas alocaria memória para dispor a nova string plana na memória. (Talvez isso deva ser otimizado)fonte
Eu sei que este é um tópico antigo, mas seu teste está incorreto. Você está fazendo
output += myarray[i];
enquanto deveria ser mais comooutput += "" + myarray[i];
porque você esqueceu, que você tem que colar itens com alguma coisa. O código concat deve ser algo como:Dessa forma, você está fazendo duas operações em vez de uma devido à colagem de elementos.
Array.join()
é mais rápido.fonte
"" +
e o original?output
sem ele.Array.join(",")
que não funcionará com seufor
loopPara uma grande quantidade de dados, a junção é mais rápida, então a questão é declarada incorretamente.
Testado no Chrome 72.0.3626.119, Firefox 65.0.1, Edge 42.17134.1.0. Observe que é mais rápido mesmo com a criação de array incluída!
fonte
Os benchmarks lá são triviais. Concatenar os mesmos três itens repetidamente será embutido, os resultados serão comprovadamente determinísticos e memoizados, o manipulador de lixo estará apenas jogando fora os objetos de array (que terão quase nada em tamanho) e provavelmente apenas empurrados e retirados da pilha devido a nenhum referências externas e porque as strings nunca mudam. Eu ficaria mais impressionado se o teste fosse um grande número de strings geradas aleatoriamente. Como em um show ou dois de cordas.
Array.join FTW!
fonte
Eu diria que com strings é mais fácil pré-alocar um buffer maior. Cada elemento tem apenas 2 bytes (se UNICODE), então mesmo se você for conservador, você pode pré-alocar um buffer bem grande para a string. Com
arrays
cada elemento é mais "complexo", porque cada elemento é umObject
, então uma implementação conservadora irá pré-alocar espaço para menos elementos.Se você tentar adicionar um
for(j=0;j<1000;j++)
antes de cada um,for
verá que (sob o cromo) a diferença na velocidade fica menor. No final, ainda era 1,5x para a concatenação de strings, mas menor do que 2,6 vezes antes.E tendo que copiar os elementos, um caractere Unicode é provavelmente menor do que uma referência a um objeto JS.
Esteja ciente de que existe a possibilidade de que muitas implementações de mecanismos JS tenham uma otimização para matrizes de tipo único que tornaria tudo o que escrevi inútil :-)
fonte
Este teste mostra a penalidade de realmente usar uma string feita com concatenação de atribuição versus feita com o método array.join. Embora a velocidade geral de atribuição ainda seja duas vezes mais rápida no Chrome v31, ela não é mais tão grande quanto quando não se usa a string resultante.
fonte
Isso depende claramente da implementação do mecanismo javascript. Mesmo para versões diferentes de um motor, você pode obter resultados significativamente diferentes. Você deve fazer seu próprio benchmark para verificar isso.
Eu diria que
String.concat
tem melhor desempenho nas versões recentes do V8. Mas para Firefox e Opera,Array.join
é um vencedor.fonte
Meu palpite é que, embora cada versão esteja usando o custo de muitas concatenações, as versões de junção estão criando matrizes além disso.
fonte