Sont les chaînes de caractères JavaScript immuable? Ai-je besoin d'un “générateur de chaîne” en JavaScript?
N'javascript utiliser immuable ou mutable cordes? Ai-je besoin d'un "générateur de chaîne"?
- Oui, la y sont immuables et vous avez besoin d'un "générateur de chaîne" d'une certaine sorte. Lire ce blog.codeeffects.com/Article/String-Builder-In-Java-Script ou le codeproject.com/KB/scripting/stringbuilder.aspx
- Intéressant, ces exemples contredisent mes conclusions dans ma réponse.
Vous devez vous connecter pour publier un commentaire.
Ils sont immuables. Vous ne pouvez pas changer un caractère dans une chaîne, avec quelque chose comme
var myString = "abbdef"; myString[2] = 'c'
. La manipulation de la chaîne des méthodes telles quetrim
,slice
retour de nouvelles chaînes.De la même manière, si vous avez deux références à la même chaîne, modification de l'un n'affecte pas les autres
Cependant, j'ai toujours entendu dire que des Cendres mentionné dans sa réponse (qui à l'aide du Tableau.jointure est plus rapide pour la concaténation) donc j'ai voulu tester les différentes méthodes de concaténation de chaînes de caractères et en faisant abstraction de la manière la plus rapide dans un StringBuilder. J'ai écrit quelques tests pour voir si c'est vrai (il ne l'est pas!).
C'était ce que je croyais serait le moyen le plus rapide, bien que je n'arrêtais pas de penser que l'ajout d'un appel de méthode peut le rendre plus lent...
Ici sont les performances à des tests de vitesse. Tous trois d'entre eux de créer une gigantesque chaîne de caractères composée de la concaténation de
"Hello diggity dog"
d'une centaine de milliers de fois en une chaîne vide.J'ai créé trois types de tests
Array.push
etArray.join
Array.push
, puis à l'aideArray.join
Puis j'ai créé le même trois essais par abstraction dans
StringBuilderConcat
,StringBuilderArrayPush
etStringBuilderArrayIndex
http://jsperf.com/string-concat-without-sringbuilder/5 s'il vous Plaît aller là-bas et exécuter les tests, donc nous pouvons obtenir un bon échantillon. Notez que j'ai corrigé un petit bug, de sorte que les données pour les tests ai effacé, je vais mettre à jour la table une fois il y a assez de données sur le rendement. Aller à http://jsperf.com/string-concat-without-sringbuilder/5 pour l'ancien tableau de données.Voici quelques chiffres (Dernière mise à jour Ma5rch 2018), si vous ne voulez pas suivre le lien. Le nombre sur chaque test est de 1 000 opérations/seconde (plus c'est mieux)
Résultats
Aujourd'hui, tous les evergreen navigateurs poignée de concaténation de chaîne bien.
Array.join
seulement aide à IE 11Dans l'ensemble, Opera est plus rapide, 4 fois plus vite que la Matrice.rejoignez
Firefox est deuxième et
Array.join
est seulement légèrement plus lente dans les FF, mais beaucoup plus lent (3x) dans Chrome.Chrome est troisième mais de chaîne concat est 3 fois plus rapide que le Tableau.rejoignez
La création d'un StringBuilder semble pas affecter les performances de trop.
Espère que quelqu'un d'autre trouve cela utile
Différents Cas De Test
Depuis @RoyTinker pensé que mon test était défectueux, j'ai créé un nouveau cas ne pas créer une chaîne de caractères par la concaténation de la même chaîne, il utilise un caractère différent pour chaque itération. La concaténation de chaîne semblait encore plus rapide ou plus rapide. Nous allons obtenir ces tests en cours d'exécution.
Je suggère que tout le monde devrait cesse de penser à d'autres façons de tester cela, et n'hésitez pas à ajouter de nouveaux liens vers les différents cas de test ci-dessous.
http://jsperf.com/string-concat-without-sringbuilder/7
join
vs concaténation de chaîne, d'où la construction du tableau avant de faire le test. Je ne pense pas que c'est de la triche si cet objectif est bien compris (etjoin
énumère le tableau en interne, de sorte qu'il n'est pas tricher omettre unfor
boucle de lajoin
test, soit).realloc
, ce qui signifie que l'optimisation ne se produit que lorsqu'il y a suffisamment d'espace libre après la fin de l'affectation. Sirealloc
a copier les vieux de la chaîne, il n'y a aucun avantage à cette méthode, et d'un constructeur est plus optimal.Array.join
Exploder
avec D. je vois ce que vous avez fait ici. 😀de la rhino livre:
null
undefined
number
etboolean
. Les chaînes de caractères sont affectés par valeur et pas par référence et sont transmis en tant que tel. Ainsi, les strings ne sont pas immuables, ils sont un valeur. La modification de la chaîne de"hello"
être"world"
est comme décider qu'à partir de maintenant, le nombre 3 est le nombre 4... il n'a pas de sens.var a = "hello";var b=a;a.x=5;console.log(a.x,b.x);
new String("...")
? J'ai trouvé ceci intéressant: "Notez que le JavaScript fait la distinction entre les objets String et primitive de la chaîne de valeurs. (La même chose est vraie de Booléens et les Nombres.)"String
les objets créés à l'aide de la chaîne de constructeur sont wrappers autour de JavaScript chaîne de valeurs. Vous pouvez accéder à la chaîne de valeur de la boîte contenant le type à l'aide de la.valueOf()
fonction - ceci est également vrai pour lesNumber
objets et le nombre de valeurs. Il est important de noterString
objets créés à l'aidenew String
ne sont pas vraiment des cordes, mais sont wrappers ou boîtes autour de chaînes de caractères. Voir es5.github.io/#x15.5.2.1 . À propos de la façon dont les choses se convertir à objets, voir es5.github.io/#x9.9str
est vraiment une sous-classe deobject
; il a tous de la normeobject
méthodes et fonctionne avec tous les génériques de premier niveau des fonctions commedir
. Il n'y a pas de concept de "primitifs types de valeur" en Python. Bien sûr, tout cela est faux en JS.Performances de pointe:
Si vous avez pour concaténer des chaînes, mettre la chaîne dans un tableau et utiliser les
Array.Join()
méthode pour obtenir l'ensemble de la chaîne. Cela peut être plusieurs fois plus rapide pour la concaténation d'un grand nombre de chaînes.Il n'y a pas de
StringBuilder
en JavaScript.Juste pour clarifier, pour les simples d'esprits comme le mien (de MDN):
Immuable signifie que:
Cela ressemble nous sommes la mutation de la chaîne de caractères "immutableString", mais nous ne sommes pas. Au lieu de cela:
La valeur de type chaîne de est immuable, mais l'objet de type String, qui est créé en utilisant la Chaîne de caractères() constructeur, est mutable, parce que c'est un objet, et vous pouvez ajouter de nouvelles propriétés.
Pendant ce temps, bien que vous pouvez ajouter de nouvelles propriétés, vous ne pouvez pas modifier l'existant propriétés
Une capture d'écran d'un test en console Chromée
En conclusion,
1. tous type de chaîne de valeur (de type primitif) est immuable.
2. L'objet de type String est mutable, mais le type de chaîne de valeur (de type primitif) qu'il contient est immuable.
new String
génère une mutable wrapper autour d'un immuable de la chaîneString
objet (wrapper), c'est à dire pas immuables (par défaut, comme tout autre objet, vous pouvez appelerObject.freeze
sur elle pour la rendre immuable). Mais une primitive de la chaîne de valeur de type, que ce soit contenue dans unString
objet wrapper ou non, est toujours immuable.Les chaînes sont immuables – ils ne peuvent pas changer, on ne peut jamais faire de nouvelles chaînes.
Exemple:
Concernant votre question (dans votre commentaire de Ash réponse) sur le StringBuilder dans ASP.NET Ajax les experts semblent en désaccord sur ce point.
Christian Wenz dit dans son livre de Programmation ASP.NET AJAX (O'Reilly) que "cette approche n'a aucun effet mesurable sur la mémoire (en fait, la mise en œuvre semble être une tique plus lent que l'approche standard)."
D'autre part Gallo et coll disent dans leur livre ASP.NET AJAX en Action (Manning) que "Lorsque le nombre de cordes pour concaténer est plus grand, le générateur de chaîne devient un objet essentiel d'éviter d'énormes performances chutent."
Je suppose que vous auriez besoin pour faire votre propre analyse comparative et les résultats peuvent différer entre les navigateurs, trop. Cependant, même si elle n'améliore pas les performances, il pourrait encore être considérés comme "utiles" pour les programmeurs qui sont utilisés pour le codage avec StringBuilders dans des langages comme C# ou Java.
C'est une fin de post, mais je n'ai pas trouver un bon livre à citer parmi les réponses.
Ici est un défini à l'exception d'un livre fiable:
Maintenant, la réponse qui cite Rhino livre de l'extrait est juste à propos de la chaîne de l'immutabilité, mais tort de dire que "les Chaînes sont attribuées par référence et non par valeur." (probablement à l'origine destiné à mettre les mots un sens opposé).
La "référence/valeur" idée fausse est précisé dans le "Professionnel JavaScript", chapitre nommé "Primitive et des valeurs de Référence":
que l'opposition à objets:
Les chaînes de caractères JavaScript, en effet, sont immuables.
Chaînes de caractères en Javascript sont immuables