O javascript usa seqüências imutáveis ou mutáveis? Preciso de um "construtor de strings"?
javascript
string
DevelopingChris
fonte
fonte
Respostas:
Eles são imutáveis. Você não pode alterar um caractere dentro de uma string com algo parecido
var myString = "abbdef"; myString[2] = 'c'
. Os métodos de manipulação de strings, comotrim
,slice
retornam novas strings.Da mesma forma, se você tiver duas referências à mesma sequência, modificar uma não afeta a outra
No entanto, sempre ouvi o que Ash mencionou em sua resposta (que usar Array.join é mais rápido para concatenação), então eu queria testar os diferentes métodos de concatenar seqüências de caracteres e abstrair a maneira mais rápida em um StringBuilder. Eu escrevi alguns testes para ver se isso é verdade (não é!).
Era o que eu achava que seria a maneira mais rápida, embora eu continuasse pensando que adicionar uma chamada de método pode torná-la mais lenta ...
Aqui estão os testes de velocidade de desempenho. Todos os três criam uma cadeia gigantesca composta de concatenação
"Hello diggity dog"
cem mil vezes em uma cadeia vazia.Eu criei três tipos de testes
Array.push
eArray.join
Array.push
, em seguida, usandoArray.join
Então eu criei os mesmos três testes abstraindo-los em
StringBuilderConcat
,StringBuilderArrayPush
eStringBuilderArrayIndex
http://jsperf.com/string-concat-without-sringbuilder/5 Por favor, vá lá e executar testes para que possamos obter uma amostra agradável. Observe que eu corrigi um pequeno bug; portanto, os dados dos testes foram apagados; atualizarei a tabela assim que houver dados de desempenho suficientes. Acesse http://jsperf.com/string-concat-without-sringbuilder/5 para obter a tabela de dados antiga.Aqui estão alguns números (última atualização no Ma5rch 2018), se você não quiser seguir o link. O número em cada teste é de 1000 operações / segundo (quanto maior, melhor )
Constatações
Atualmente, todos os navegadores sempre verdes lidam bem com a concatenação de strings.
Array.join
só ajuda o IE 11No geral, o Opera é mais rápido, 4 vezes mais rápido que o Array.join
O Firefox é o segundo e
Array.join
é apenas um pouco mais lento no FF, mas consideravelmente mais lento (3x) no Chrome.O Chrome é o terceiro, mas o concat de strings é 3 vezes mais rápido que o Array.join
Criar um StringBuilder parece não afetar muito o desempenho.
Espero que alguém ache isso útil
Caso de teste diferente
Como o @RoyTinker achou que meu teste era defeituoso, criei um novo caso que não cria uma grande string concatenando a mesma string, ele usa um caractere diferente para cada iteração. A concatenação de cordas ainda parecia mais rápida ou mais rápida. Vamos executar esses testes.
Sugiro que todos continuem pensando em outras maneiras de testar isso e fique à vontade para adicionar novos links para diferentes casos de teste abaixo.
http://jsperf.com/string-concat-without-sringbuilder/7
fonte
join
concatenação de vs strings, criando assim a matriz antes do teste. Eu não acho que isso é trapaça se esse objetivo for entendido (ejoin
enumera a matriz internamente, portanto, não é trapaça omitir umfor
loop dojoin
teste).Array.join
do livro rinoceronte :
fonte
null
undefined
number
eboolean
. As strings são atribuídas por valor e não por referência e são passadas como tal. Assim, as strings não são apenas imutáveis, elas são um valor . Mudar a string"hello"
para ser"world"
é como decidir que a partir de agora o número 3 é o número 4 ... não faz sentido.var a = "hello";var b=a;a.x=5;console.log(a.x,b.x);
String
objetos criados usando o construtor de strings são wrappers em torno dos valores de strings JavaScript. Você pode acessar o valor da sequência do tipo em caixa usando a.valueOf()
função - isso também é válido paraNumber
objetos e valores numéricos. É importante observar que osString
objetos criados usandonew String
não são cadeias reais, mas são invólucros ou caixas em torno das cadeias. Consulte es5.github.io/#x15.5.2.1 . Sobre como as coisas converter em objetos ver es5.github.io/#x9.9Dica de desempenho:
Se você precisar concatenar cadeias grandes, coloque as partes em uma matriz e use o
Array.Join()
método para obter a cadeia geral. Isso pode ser muitas vezes mais rápido para concatenar um grande número de strings.Não há
StringBuilder
no JavaScript.fonte
Apenas para esclarecer mentes simples como a minha (da MDN ):
Imutável significa que:
Parece que estamos mudando a string 'immutableString', mas não estamos. Em vez de:
fonte
O valor do tipo string é imutável, mas o objeto String, criado usando o construtor String (), é mutável, porque é um objeto e você pode adicionar novas propriedades.
Enquanto isso, embora você possa adicionar novas propriedades, não é possível alterar as propriedades já existentes.
Captura de tela de um teste no console do Chrome
Em conclusão, 1. todo o valor do tipo string (tipo primitivo) é imutável. 2. O objeto String é mutável, mas o valor do tipo de string (tipo primitivo) que ele contém é imutável.
fonte
new String
gera um invólucro mutável em torno de uma seqüência imutávelString
objeto (invólucro), o que significa que não é imutável (por padrão; como qualquer outro objeto que você pode chamarObject.freeze
para torná-lo imutável). Mas um tipo de valor de cadeia primitivo, contidoString
ou não em um invólucro de objeto, é sempre imutável.Strings são imutáveis - elas não podem mudar, só podemos criar novas strings.
Exemplo:
fonte
Em relação à sua pergunta (no seu comentário à resposta de Ash) sobre o StringBuilder no ASP.NET Ajax, os especialistas parecem discordar.
Christian Wenz diz em seu livro Programming ASP.NET AJAX (O'Reilly) que "essa abordagem não tem nenhum efeito mensurável na memória (de fato, a implementação parece ser um tique mais lento que a abordagem padrão)".
Por outro lado, Gallo e colaboradores dizem em seu livro ASP.NET AJAX in Action (Manning) que "quando o número de seqüências de caracteres para concatenar é maior, o construtor de seqüências de caracteres se torna um objeto essencial para evitar grandes quedas de desempenho".
Acho que você precisaria fazer seu próprio benchmarking e os resultados também podem diferir entre os navegadores. No entanto, mesmo que não melhore o desempenho, ainda pode ser considerado "útil" para programadores acostumados a codificar com StringBuilders em linguagens como C # ou Java.
fonte
É um post tardio, mas não encontrei uma boa citação de livro entre as respostas.
Aqui está uma definição, exceto em um livro confiável:
Agora, a resposta que cita o trecho do livro Rhino está certa sobre imutabilidade de strings, mas está errado dizer "Strings são atribuídos por referência, não por valor". (provavelmente eles originalmente pretendiam colocar as palavras de maneira oposta).
O equívoco "referência / valor" é esclarecido no capítulo "JavaScript profissional", chamado "Valores primitivos e de referência":
isso é contra objetos :
fonte
As strings JavaScript são realmente imutáveis.
fonte
Strings em Javascript são imutáveis
fonte