Самый эффективный способ генерации действительно длинной строки (десятки мегабайт) в JS

Мне нужно синтезировать смехотворно длинную строку (например, десятки мегабайт в длину) в JavaScript. (Это должно замедлить операцию выбора селектора CSS до точки, где требуется измеримое количество времени.)

Лучший способ, которым я нашел это, -

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

но мне интересно, есть ли более эффективный способ - тот, который не включает создание массива с десятками мегабайт.

Ответы

Ответ 1

В принятой версии используется String.prototype.concat(), который значительно медленнее, чем использование оптимизированного оператора конкатенации строк +. MDN также рекомендует избегать использования его в критическом кривом скорости.

Я сделал три версии вышеуказанного кода, чтобы показать разницу в скорости в JsPerf. Преобразование его в использование только с помощью concat - это только третья так же быстро, как только использование оператора конкатенации строк (Chrome - ваш пробег будет отличаться). Отредактированная версия ниже будет работать в два раза быстрее в Chrome

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

Ответ 2

Это более эффективный алгоритм для генерации очень длинных строк в 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;
}

подробнее здесь: http://www.2ality.com/2014/01/efficient-string-repeat.html.

В качестве альтернативы, в ECMA6 вы можете использовать метод String.prototype.repeat().

Ответ 3

Простое накопление значительно быстрее в Safari 5:

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

По существу, вы получите символы x.length * 3^iterations.

Ответ 4

Не уверен, что это отличная реализация, но здесь общая функция, основанная на решении @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;
}

Это предполагает, что конкатенация большой строки выполняется быстрее, чем серия небольших строк.