web-dev-qa-db-fra.com

l'opérateur + est moins performant que StringBuffer.append ()

Dans mon équipe, nous effectuons généralement une concaténation de chaînes comme suit:

var url = // some dynamically generated URL
var sb = new StringBuffer();
sb.append("<a href='").append(url).append("'>click here</a>");

Évidemment, ce qui suit est beaucoup plus lisible:

var url = // some dynamically generated URL
var sb = "<a href='" + url + "'>click here</a>";

Mais les experts JS affirment que l’opérateur + Est moins performant que StringBuffer.append(). Est-ce vraiment vrai?

89
Dónal

Internet Explorer est le seul navigateur qui en souffre vraiment dans le monde d'aujourd'hui. (Les versions 5, 6 et 7 ont été lentes. 8 ne montre pas la même dégradation.) De plus, IE ralentit et ralentit la longueur de votre chaîne.

Si vous avez de longues chaînes à concaténer, utilisez une technique array.join. (Ou un encapsuleur StringBuffer autour de ceci, pour plus de lisibilité.) Mais si vos chaînes sont courtes, ne vous dérangez pas.

46
pcorcoran

Votre exemple n’est pas bon en ce sens qu’il est très peu probable que la performance soit sensiblement différente. Dans votre exemple, la lisibilité devrait avoir un impact négatif sur les performances car le gain de performance de l’un par rapport à l’autre est négligeable. Les avantages d'un tableau (StringBuffer) ne sont apparents que lorsque vous effectuez de nombreuses concatentations. Même dans ce cas, votre kilométrage peut varier en fonction de votre navigateur.

Voici une analyse de performance détaillée qui montre les performances en utilisant toutes les méthodes de concaténation JavaScript différentes sur de nombreux navigateurs différents. Analyse de la performance d'une chaîne

join() once, concat() once, join() for, += for, concat() for

Plus:
Ajaxian >> Performance de la chaîne dans IE: Array.join vs + = suite

102
Eric Schoonover

Oui c'est vrai mais vous ne devriez pas vous en soucier. Allez avec celui qui est plus facile à lire. Si vous devez analyser votre application, concentrez-vous sur les goulots d'étranglement.

J'imagine que cette concaténation de chaînes ne sera pas votre goulot d'étranglement.

37
Michael Haren

D'accord avec Michael Haren .

Pensez également à l’utilisation de tableaux et à la jointure si les performances sont réellement problématiques.

var buffer = ["<a href='", url, "'>click here</a>"];
buffer.Push("More stuff");
alert(buffer.join(""));
31
Frank Krueger

Essaye ça:

var s = ["<a href='", url, "'>click here</a>"].join("");
18
Rahul

JavaScript n'a pas d'objet StringBuffer natif, donc je suppose que cela provient d'une bibliothèque que vous utilisez ou d'une fonctionnalité d'un environnement hôte inhabituel (c'est-à-dire pas un navigateur).

Je doute qu'une bibliothèque (écrite en JS) puisse produire quoi que ce soit plus rapidement, bien qu'un objet natif StringBuffer puisse le faire. La réponse définitive peut être trouvée avec un profileur (si vous utilisez un navigateur, alors Firebug vous fournira un profileur pour le moteur JS de Firefox).

8
Quentin

Comme déjà noté par certains utilisateurs: Ceci n'est pas pertinent pour les petites chaînes.

Et les nouveaux moteurs JavaScript dans Firefox, Safari ou Google Chrome optimiser

"<a href='" + url + "'>click here</a>";

est aussi rapide que

["<a href='", url, "'>click here</a>"].join("");
7
amix

Selon les mots de Knuth, "l'optimisation prématurée est la racine de tout le mal!" La petite différence dans l'un ou l'autre sens n'aura probablement pas beaucoup d'effet à la fin; Je choisirais le plus lisible.

6
William Keller

La méthode la plus facile à lire permet de gagner du temps perceptible lorsque vous examinez le code, tandis que la méthode "plus rapide" ne fait que perdre un temps imperceptible et probablement négligeable lorsque vous parcourez la page.

Je sais que cet article est boiteux, mais j'ai accidentellement posté quelque chose de complètement différent en pensant que c'était un fil différent et je ne sais pas comment supprimer des messages. Ma faute...

4
Ed Kern

Il est assez facile de configurer un test rapide et de vérifier les variations de performances Javascript à l'aide de jspref.com . Ce qui n'était probablement pas autour quand cette question a été posée. Mais pour ceux qui trébuchent sur cette question, ils devraient prendre alook sur le site.

J'ai fait un test rapide de diverses méthodes de concaténation sur http://jsperf.com/string-concat-methods-test .

3
James McMahon

J'aime utiliser un style fonctionnel, tel que:

function href(url,txt) {
  return "<a href='" +url+ "'>" +txt+ "</a>"
}

function li(txt) {
  return "<li>" +txt+ "</li>"
}

function ul(arr) {
  return "<ul>" + arr.map(li).join("") + "</ul>"
}

document.write(
  ul(
    [
      href("http://url1","link1"),
      href("http://url2","link2"),
      href("http://url3","link3")
    ]
  )
)

Ce style a l'air lisible et transparent. Cela conduit à la création d’utilitaires qui réduisent la répétition dans le code.

Cela tend également à utiliser automatiquement des chaînes intermédiaires.

2
jasonc65

Autant que je sache, chaque concaténation implique une réallocation de mémoire. Le problème n'est donc pas l'opérateur utilisé pour le faire, la solution est de réduire le nombre de concaténations. Par exemple, faites les concaténations en dehors des structures d'itération lorsque vous le pouvez.

1
David Ameller

Oui, selon les repères habituels. E.G: http://mckoss.com/jscript/SpeedTrial.htm .

Mais pour les petites ficelles, ce n'est pas pertinent. Vous ne vous intéresserez qu'aux performances sur de très grandes cordes. De plus, dans la plupart des scripts JS, le goulot d'étranglement est rarement utilisé sur les cordes, car il n'en contient pas assez.

Vous feriez mieux de regarder la manipulation du DOM.

0
e-satis