2010-09-17 15 views
13

Me resulta necesario sintetizar una secuencia ridículamente larga (como decenas de megabytes de longitud) en JavaScript. (Esto es para reducir la velocidad de una operación CSS selector de coincidencia hasta el punto en que se necesita una cantidad medible de tiempo.)La forma más eficiente de generar una cadena realmente larga (decenas de megabytes) en JS

La mejor manera que he encontrado para hacer esto es

var really_long_string = (new Array(10*1024*1024)).join("x"); 

pero yo' Me pregunto si hay una manera más eficiente, una que no implique crear una matriz de decenas de megabytes primero.

Respuesta

12

La versión aceptada usa String.prototype.concat() que es vastly slower que utilizando el operador de concatenación de cuerda optimizado, +. MDN también recommends para evitar usarlo en el código de velocidad crítica.

He hecho three versions del código anterior para mostrar las diferencias de velocidad en un JsPerf. Convertirlo a usar solo usando concat es solo un tercio más rápido que solo usar el operador de concatenación de cuerdas (Chrome: el kilometraje puede variar). La versión editada a continuación se ejecutará dos veces más rápido en Chrome

var x = "1234567890"; 
var iterations = 14; 
for (var i = 0; i < iterations; i++) { 
    x += x+x; 
} 
+0

http://www.sitepoint.com/javascript-fast-string-concatenation/ –

3

Simplemente acumulación es mucho más rápido en Safari 5:

var x = "1234567890"; 
var iterations = 14; 
for (var i = 0; i < iterations; i++) { 
    x += x.concat(x); 
} 
alert(x.length); // 47829690 

Esencialmente, usted obtendrá x.length * 3^iterations caracteres.

+0

Me las arreglé para matar a un proceso de contenido de Chrome con la construcción original – zwol

+0

Su enfoque también es mucho más rápido con Firefox. Lo tracé; ambos toman tiempo proporcional a la longitud de la cadena, pero la técnica Array se vuelve inaceptablemente lenta a 2^20 bytes (un megabyte, no lo suficiente) donde la técnica de concatenación es aún tolerable a 2^26 o así (64 megabytes, mucho más de lo que necesito). – zwol

4

Este es el algoritmo más eficiente para la generación de cadenas muy largas en javascript:

function stringRepeat(str, num) { 
    num = Number(num); 

    var result = ''; 
    while (true) { 
     if (num & 1) { // (1) 
      result += str; 
     } 
     num >>>= 1; // (2) 
     if (num <= 0) break; 
     str += str; 
    } 

    return result; 
} 

más información aquí: http://www.2ality.com/2014/01/efficient-string-repeat.html.

Alternativamente, en ECMA6 puede usar el método String.prototype.repeat().

0

No estoy seguro si esto es una gran aplicación, pero aquí es una función general basado en la solución de @ oligofren:

function repeat(ch, len) { 
    var result = ch; 
    var halfLength = len/2; 
    while (result.length < len) { 
    if (result.length <= halfLength) { 
     result += result; 
    } else { 
     return result + repeat(ch, len - result.length); 
    } 
    } 

    return result; 
} 

Esto supone que la concatenación de una cadena grande es más rápido que una serie de pequeñas cadenas.

Cuestiones relacionadas