Hoy, leí este hilo sobre la velocidad de la concatenación de cadenas.
Sorprendentemente, la concatenación de cadenas fue la ganadora:
El resultado fue contrario a lo que pensaba. Además, hay muchos artículos sobre esto que explican lo contrario de esta manera .
Puedo suponer que los navegadores están optimizados para encadenar concat
en la última versión, pero ¿cómo lo hacen? ¿Podemos decir que es mejor usarlo +
al concatenar cadenas?
Actualizar
Entonces, en los navegadores modernos, la concatenación de cadenas está optimizada, por lo que usar +
signos es más rápido que usar join
cuando desea concatenar cadenas.
Pero @Arthur señaló que join
es más rápido si realmente desea unir cadenas con un separador.
Actualización - 2020
Chrome: Array join
casi 2 times faster
es String concat +
Consulte: https://stackoverflow.com/a/54970240/984471
Como nota:
- Array
join
es mejor si tieneslarge strings
- Si necesitamos generar
several small strings
en la salida final, es mejor ir con string concat+
, ya que de lo contrario, ir con Array necesitará varias conversiones de Array a String al final, lo cual es una sobrecarga de rendimiento.
fuente
Respuestas:
El motor javascript V8 (utilizado en Google Chrome) utiliza este código para realizar la concatenación de cadenas:
Entonces, internamente lo optimizan creando un InternalArray (la
parts
variable), que luego se llena. La función StringBuilderConcat se llama con estas partes. Es rápido porque la función StringBuilderConcat es un código C ++ muy optimizado. Es demasiado largo para citar aquí, pero busque en el archivo runtime.cc paraRUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat)
ver el código.fuente
arr.join vs str+
en Chrome obtienes (en operaciones por segundo)25k/s vs 52k/s
. en firefox nuevo obtienes76k/s vs 212k/s
. tambiénstr+
es MÁS RÁPIDO. pero veamos otros navegadores. Opera da 43k / s frente a 26k / s. IE da1300/s vs 1002/s
. ¿mira qué pasa? el único navegador que NECESITA optimización estaría mejor usando el que es más lento en todos los demás, donde no importa en absoluto. Entonces, ninguno de esos artículos comprende nada sobre el rendimiento.Firefox es rápido porque usa algo llamado Ropes ( Ropes: an Alternative to Strings ). Una cuerda es básicamente un DAG, donde cada nodo es una cuerda.
Entonces, por ejemplo, si lo hiciera
a = 'abc'.concat('def')
, el objeto recién creado se vería así. Por supuesto, esto no es exactamente cómo se ve esto en la memoria, porque aún necesita tener un campo para el tipo de cadena, la longitud y tal vez otros.Y
b = a.concat('123')
Entonces, en el caso más simple, la VM casi no tiene que hacer ningún trabajo. El único problema es que esto ralentiza un poco otras operaciones en la cadena resultante. También esto, por supuesto, reduce la sobrecarga de memoria.
Por otro lado
['abc', 'def'].join('')
, normalmente solo asignaría memoria para colocar la nueva cadena plana en la memoria. (Quizás esto debería optimizarse)fuente
Sé que este es un hilo antiguo, pero tu prueba es incorrecta. Lo estás haciendo
output += myarray[i];
mientras debería ser más bienoutput += "" + myarray[i];
porque te olvidaste que tienes que pegar elementos con algo. El código de concat debería ser algo como:De esa manera, está haciendo dos operaciones en lugar de una debido a pegar elementos.
Array.join()
es más rápido.fuente
"" +
y el original?output
sin él.Array.join(",")
lo que no funcionará con sufor
buclePara una gran cantidad de datos, la combinación es más rápida, por lo que la pregunta se formula incorrectamente.
Probado en Chrome 72.0.3626.119, Firefox 65.0.1, Edge 42.17134.1.0. ¡Tenga en cuenta que es más rápido incluso con la creación de matrices incluida!
fuente
Los puntos de referencia son triviales. La concatenación de los mismos tres elementos repetidamente se incluirá en línea, los resultados demostrarán ser deterministas y memorizados, el controlador de basura simplemente arrojará objetos de matriz (que tendrán un tamaño casi nulo) y probablemente simplemente empujará y saldrá de la pila debido a que no referencias externas y porque las cadenas nunca cambian. Me impresionaría más si la prueba fuera una gran cantidad de cadenas generadas aleatoriamente. Como en un concierto o dos de cuerdas.
¡Únete a FTW!
fuente
Yo diría que con cadenas es más fácil preasignar un búfer más grande. Cada elemento tiene solo 2 bytes (si es UNICODE), por lo que incluso si es conservador, puede preasignar un búfer bastante grande para la cadena. Con
arrays
cada elemento es más "complejo", porque cada elemento es unObject
, por lo que una implementación conservadora preasignará espacio para menos elementos.Si intenta agregar un
for(j=0;j<1000;j++)
antes de cadafor
uno, verá que (debajo de cromo) la diferencia de velocidad se reduce. Al final, todavía era 1.5x para la concatenación de cadenas, pero más pequeño que el 2.6 que era antes.Y teniendo que copiar los elementos, un carácter Unicode probablemente sea más pequeño que una referencia a un objeto JS.
Tenga en cuenta que existe la posibilidad de que muchas implementaciones de motores JS tengan una optimización para matrices de un solo tipo que haría que todo lo que he escrito sea inútil :-)
fuente
Esta prueba muestra la penalización de usar realmente una cadena hecha con concatenación de asignaciones versus hecha con el método array.join. Si bien la velocidad general de asignación sigue siendo dos veces más rápida en Chrome v31, ya no es tan grande como cuando no se usa la cadena resultante.
fuente
Esto depende claramente de la implementación del motor javascript. Incluso para diferentes versiones de un motor, puede obtener resultados significativamente diferentes. Debe hacer su propio punto de referencia para verificar esto.
Yo diría que
String.concat
tiene mejor rendimiento en las últimas versiones de V8. Pero para Firefox y Opera,Array.join
es un ganador.fuente
Supongo que, si bien cada versión tiene el costo de muchas concatenaciones, las versiones de unión están construyendo matrices además de eso.
fuente