Pregunta

En mi equipo, normalmente hacemos concatenación de cadenas como esta:

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

Obviamente lo siguiente es mucho más legible:

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

Pero los expertos de JS afirman que + El operador tiene menos rendimiento que StringBuffer.append().¿Es esto realmente cierto?

¿Fue útil?

Solución

Internet Explorer es el único navegador que realmente sufre esto en el mundo actual.(Las versiones 5, 6 y 7 eran muy lentas.8 no muestra la misma degradación). Es más, IE se vuelve cada vez más lento cuanto más larga es la cadena.

Si tiene cadenas largas para concatenar, definitivamente use una técnica array.join.(O algún contenedor StringBuffer alrededor de esto, para facilitar la lectura). Pero si sus cadenas son cortas, no se moleste.

Otros consejos

Su ejemplo no es bueno porque es muy poco probable que el desempeño sea significativamente diferente.En su ejemplo, la legibilidad debería prevalecer sobre el rendimiento porque la ganancia de rendimiento de uno frente al otro es insignificante.Los beneficios de una matriz (StringBuffer) solo son evidentes cuando se realizan muchas concatenaciones.Incluso entonces, su kilometraje puede depender mucho de su navegador.

Aquí hay un análisis de rendimiento detallado que muestra el rendimiento utilizando todos los diferentes métodos de concatenación de JavaScript en muchos navegadores diferentes; Análisis y rendimiento de cuerdas

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

Más:
Ajaxian >> Rendimiento de cadenas en IE:Array.join vs += continuación

Sí, es verdad, pero no debería importarte.Elija el que sea más fácil de leer.Si tiene que comparar su aplicación, concéntrese en los cuellos de botella.

Supongo que la concatenación de cadenas no será su cuello de botella.

De acuerdo con michael haren.

Considere también el uso de matrices y únase si el rendimiento es realmente un problema.

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

Prueba esto:

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

JavaScript no tiene un objeto StringBuffer nativo, por lo que supongo que proviene de una biblioteca que está utilizando o de una característica de un entorno de host inusual (es decir,no es un navegador).

Dudo que una biblioteca (escrita en JS) produzca algo más rápido, aunque un objeto StringBuffer nativo podría hacerlo.La respuesta definitiva se puede encontrar con un generador de perfiles (si está ejecutando un navegador, Firebug le proporcionará un generador de perfiles para el motor JS que se encuentra en Firefox).

Como ya han notado algunos usuarios:Esto es irrelevante para cadenas pequeñas.

Y los nuevos motores JavaScript en Firefox, Safari o Google Chrome lo optimizan para que

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

es tan rápido como

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

En palabras de Knuth, "¡La optimización prematura es la raíz de todo mal!" La pequeña deferencia de cualquier manera probablemente no tendrá mucho efecto al final;Yo elegiría el más legible.

El método más fácil de leer ahorra a los humanos cantidades perceptibles de tiempo cuando miran el código, mientras que el método "más rápido" sólo desperdicia cantidades de tiempo imperceptibles y probablemente insignificantes cuando las personas navegan por la página.

Sé que esta publicación es aburrida, pero accidentalmente publiqué algo completamente diferente pensando que era un hilo diferente y no sé cómo eliminar publicaciones.Culpa mía...

Es bastante fácil configurar un punto de referencia rápido y comprobar las variaciones de rendimiento de Javascript utilizando jspref.com.Lo cual probablemente no existía cuando se hizo esta pregunta.Pero las personas que se topan con esta pregunta deberían echar un vistazo al sitio.

Hice una prueba rápida de varios métodos de concatenación en http://jsperf.com/string-concat-methods-test.

Me gusta usar estilos funcionales, como:

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")
    ]
  )
)

Este estilo parece legible y transparente.Conduce a la creación de utilidades que reducen la repetición del código.

Esto también tiende a utilizar cadenas intermedias de forma automática.

Hasta donde yo sé, cada concatenación implica una reasignación de memoria.Entonces el problema no es el operador utilizado para hacerlo, la solución es reducir el número de concatenaciones.Por ejemplo, haga las concatenaciones fuera de las estructuras de iteración cuando pueda.

Sí, según los puntos de referencia habituales.P.EJ : http://mckoss.com/jscript/SpeedTrial.htm.

Pero para las cadenas pequeñas, esto es irrelevante.Sólo te importarán las interpretaciones en cuerdas muy grandes.Es más, en la mayoría de los scripts JS, el cuello de botella rara vez está en las manipulaciones de cadenas, ya que no hay suficiente.

Será mejor que observes la manipulación del DOM.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top