EcmaScript 6

La concatenación de cadenas es una de las operaciones que con más frecuencia se repiten en los desarrollos de aplicaciones. Es por ello, realizar dicha operación de forma óptima incrementará el rendimiento y disminuirá el uso de recursos de nuestra aplicación. En este banco de pruebas vamos a observar trescuatro funciones distintas para realizar concatenar y descubrir cuál es la más rápida.

Función 1. Concatenación por instrucción

En esta primera función, se irá concatenando en cada instrucción una cadena. Se presenta el problema que así se genera una cadena nueva en cada concatenación, lo que provoca un mayor consumo de memoria. Pero presenta la ventaja de que no es necesario conocer de antemano cuantas cadenas intervienen en la operación.

function concatenate() {
    var text = '',
        values = ['12', '23', '34', '45', '56'];

    for (j = 0; j < 5; ++j) {
        text += values[j];
    }
}

Función 2. Concatenación con arrays

En varios artículos y libros he llegado a leer que una alternativa al uso de concatenación estándar, es ir añadiendo cadenas a un array y luego realizar una operación join() con cadena vacía. Como se observará en los resultados, esta operación es la más lenta.

function concatenate() {
    var text = [],
        values = ['12', '23', '34', '45', '56'];

    for (j = 0; j < 5; ++j) {
        text.push(values[j]);
    }

    text = text.join('');
}

Función 3. Concatenación en una instrucción

En esta ocasión, se realizan todas las operaciones de concatenación en una única instrucción. Claro para esta alternativa es necesario conocer de antemano cuales son las variables y cadenas a concatenar, pero es sin lugar a dudas la más rápida.

function concatenate() {
    var text = '',
        values = ['12', '23', '34', '45', '56'];

    // Se mantiene por similitud con las otras funciones, para que compute en los tiempos.
    for (j = 0; j < 5; ++j) {
    }
	
	text = values[0] + values[1] + values[2] + values[3] + values[4];
}

Nueva Función 4. Interpolación de cadenas

En el estándar ES6 se ha incluido la interpolación de cadenas, esto es, que se pueden introducir valores de variables dentro de una cadena (lo veremos en profundidad en un futuro artículo). En esta ocasión el rendimiento es más rápido que la función 1, pero recordad que hay que revisar la compatibilidad con todos los navegadores.

function concatenate() {
    var text = '',
        values = ['12', '23', '34', '45', '56'];

    // Se mantiene por similitud con las otras funciones, para que compute en los tiempos.
    for (j = 0; j < 5; ++j) {
    }

    text = `${values[0]}${values[1]}${values[2]}${values[3]}${values[4]}`
}

La batería de pruebas

El código para todas las pruebas será el mismo, por un lado tendremos un HTML muy básico que mostrará una tabla de resultados:

<table>
    <tr id="data">
        <th>Results</th>
    </tr>
</table>

Por otro lado, el código de pruebas también es muy sencillo. Consiste en una función que realiza un bucle de 10 pasos, en el que en cada paso se llama diez millones de veces a la función encargada de concatenar las cinco cadenas. Por otro lado, se dispone de una función con la que se añade cada resultado a la tabla HTML (Se podría haber mostrado por consola simplemente, pero así queda más visual).

function addResult(value, row, last) {
    var node = document.createElement(last ? 'th' : 'td'),
        textnode = document.createTextNode(value);

    node.appendChild(textnode);
    row.appendChild(node);
}

function test() {
    var roundTime = 0,
        row = document.getElementById('data'),
        lap, startTime, i, endTime, currentResult;

    for (lap = 0; lap < 10; ++lap) {
        startTime = new Date();
        for (i = 0; i < 10000000; ++i) {
            concatenar();
        }
        endTime = new Date();

        currentResult = endTime.getTime() - startTime.getTime()
        roundTime += currentResult;
        addResult(currentResult, row, false);
    }

    addResult((roundTime / 10) + 'ms', row, true);
}

Resultados

Una vez ejecutadas nuestras tres funciones de pruebas, se obtienen los siguientes resultados:

Función Paso 1 Paso 2 Paso 3 Paso 4 Paso 5 Paso 6 Paso 7 Paso 8 Paso 9 Paso 10 Media
1 824 816 819 815 810 810 816 816 812 811 814.9
2 2876 2767 2763 2760 2771 2774 2968 3102 3006 2941 2872.8
3 152 164 163 163 164 161 164 165 166 162 162.4
4 655 666 656 663 663 657 666 668 661 673 662.8

Tras las pruebas, se observa una clara vencedora, la función 3 de concatenación en una instrucción, ya que es casi 8 veces más rápida que la función 1, y 25 veces más rápida que la función 2. El único inconveniente es que sólo podemos usarla cuando conozcamos de antemano todos los valores a concatenar, si no es así, tendremos que utilizar la función 1. Finalmente, el uso de interpolación que admite ES6, ofrece un mejor rendimiento que la función 1, pero al igual que la 3 sigue teniendo el problema de requerir conocer el número de parámetros.

Enlaces:
Función 1 en JSFiddle
Función 2 en JSFiddle
Función 3 en JSFiddle
Función 4 en JSFiddle

Comparte este artículo con quien quieras
Internacionalización en ES6 2: La clase DateTimeFormat
Internacionalización en ES6 (y 3): La clase NumberFormat

Leave a Comment

Your email address will not be published. Required fields are marked *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.