Most efficient way to generate a really long string (tens of megabytes) in JS
I find myself needing to synthesize a ridiculously long string (like, tens of megabytes long) in JavaScript. (This is开发者_StackOverflow社区 to slow down a CSS selector-matching operation to the point where it takes a measurable amount of time.)
The best way I've found to do this is
var really_long_string = (new Array(10*1024*1024)).join("x");
but I'm wondering if there's a more efficient way - one that doesn't involve creating a tens-of-megabytes array first.
For ES6:
'x'.repeat(10*1024*1024)
The previously accepted version uses String.prototype.concat()
which is vastly slower than using the optimized string concatenating operator, +
. MDN also recommends to keep away from using it in speed critical code.
I have made three versions of the above code to show the speed differences in a JsPerf. Converting it to using only using concat
is only a third as fast as only using the string concatenating operator (Chrome - your mileage will vary). The edited version below will run twice as fast in Chrome
var x = '1234567890'
var iterations = 14
for (var i = 0; i < iterations; i++) {
x += x + x
}
This is the more efficient algorithm for generating very long strings in 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;
}
more info here: http://www.2ality.com/2014/01/efficient-string-repeat.html.
Alternatively, in ECMA6 you can use String.prototype.repeat() method.
Simply accumulating is vastly faster in Safari 5:
var x = "1234567890";
var iterations = 14;
for (var i = 0; i < iterations; i++) {
x += x.concat(x);
}
alert(x.length); // 47829690
Essentially, you'll get x.length * 3^iterations
characters.
Not sure if this is a great implementation, but here's a general function based on @oligofren's solution:
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;
}
This assumes that concatenating a large string is faster than a series of small strings.
精彩评论