function str_repeat ( input, multiplier ) { // Repeat a string
//
// + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
var buf = '';
for (i=0; i < multiplier; i++){
buf += input;
}
return buf;
}
Примеры:
str_repeat('-=', 10);
'-=-=-=-=-=-=-=-=-=-='
Автор: Гость (не зарегистрирован), дата: 16 ноября, 2009 - 17:05
Неудачная реализация. На каждой итерации realloc памяти.
new Array(10 + 1).join('-=') гораздо эффективнее, так как сперва подсчитает размер результатирующей строки.
Привожу собственную реализацию (по сути, развитие оригинальной):
// author K. Krylov (mailto:crylove_const@mail.ru)
function str_repeat ( input, multiplier )
{
var buf = '';
while (multiplier)
{
if (multiplier & 1)
buf += string;
string += string;
multiplier >>= 1;
}
return buf;
}
Написал тест производительности, чтобы узнать, какая реализация из трёх на самом деле наиболее удачная. Для того, чтобы тест был более или менее адекватным разбил тест на 6 серий по количеству возможных перестановок 3 циклов с функциями. А потом просуммировал полученное время выполнения для каждой функции.
множимая строка - '-='
множитель - 3
количество проходов в цикле - 2400000
Из результатов тестирования следует, что реализация с использованием массива является самой неудачной. Реализация, предложенная в статье эффективна при значении множителя < 15. Если же требуется размножить строку более чем 15 раз, то моя реализация будет работать быстрее.
Если заинтересовал или вызвал сомнения тест производительности, пишите, пришлю.
to Plumbum,
если есть возможность, попробуйте такую функцию протестировать:
function strRepeat(rptStr, repeatCount){
/*Такой метод повтора строк гораздо эффективнее, чем простой набор строки в цикле, т.к. экономит кучу итераций циклов*/
if (repeatCount < 1) return '';
var pow = 0;
var _pow;
var str = rptStr;
while ((repeatCount / 2).toFixed(1) >= (_pow = Math.pow(2, pow)))
{
++pow;
str += str;
}
var i = Math.floor(Number(repeatCount / _pow) - 1);
while (i > 0){
--i;
str += str;
}
repeatCount -= _pow * (++i);
return str + this.strRepeat(rptStr, repeatCount);
}
(function(repeatCount){
var log = '';
var t = (new Date()).getTime();
strRepeat('a', repeatCount);
log += 'strRepeat time: ' + ((new Date()).getTime() - t) + ' ; ';
console.log(log);
})(10000000);
10 000 000 повторов - это не ошибка. Я уже раз 20 ее запустил, но результат один и тот же... и крайне сомнительный... Но оригинальный вариант, приведенный в топе, вообще убил браузер на таком количестве итераций... При этом длина склеиваемой строки большого значения не играет: я пробовал как отдельный символ, так и полный алфавит...
На малых значениях проверял вручную результат - вроде все, что должно получиться, на месте...
Теоретически эту функцию можно ускорить еще...
Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены. Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
еще один вариант
>>> new Array(10).join('-=')
"-=-=-=-=-=-=-=-=-="
Чтобы результат был точно как в оригинале, нужна маленькая поправка:
>>> new Array(10 + 1).join('-=')
Неудачная реализация. На каждой итерации realloc памяти.
new Array(10 + 1).join('-=') гораздо эффективнее, так как сперва подсчитает размер результатирующей строки.
Привожу собственную реализацию (по сути, развитие оригинальной):
Написал тест производительности, чтобы узнать, какая реализация из трёх на самом деле наиболее удачная. Для того, чтобы тест был более или менее адекватным разбил тест на 6 серий по количеству возможных перестановок 3 циклов с функциями. А потом просуммировал полученное время выполнения для каждой функции.
множимая строка - '-='
множитель - 3
количество проходов в цикле - 2400000
оригинальная реализация - 1315 мс
реализация с массивом - 5760 мс
собственная реализация - 2241 мс
множитель - 7
количество проходов в цикле - 1200000
оригинальная реализация - 864 мс
реализация с массивом - 4221 мс
собственная реализация - 1908 мс
множитель - 13
количество проходов в цикле - 600000
оригинальная реализация - 939 мс
реализация с массивом - 2441 мс
собственная реализация - 1150 мс
множитель - 20
количество проходов в цикле - 600000
оригинальная реализация - 1572 мс
реализация с массивом - 3577 мс
собственная реализация - 1172 мс
множитель - 100
количество проходов в цикле - 300000
оригинальная реализация - 4341 мс
реализация с массивом - 5236 мс
собственная реализация - 1212 мс
Из результатов тестирования следует, что реализация с использованием массива является самой неудачной. Реализация, предложенная в статье эффективна при значении множителя < 15. Если же требуется размножить строку более чем 15 раз, то моя реализация будет работать быстрее.
Если заинтересовал или вызвал сомнения тест производительности, пишите, пришлю.
to Plumbum,
если есть возможность, попробуйте такую функцию протестировать:
10 000 000 повторов - это не ошибка. Я уже раз 20 ее запустил, но результат один и тот же... и крайне сомнительный... Но оригинальный вариант, приведенный в топе, вообще убил браузер на таком количестве итераций... При этом длина склеиваемой строки большого значения не играет: я пробовал как отдельный символ, так и полный алфавит...
На малых значениях проверял вручную результат - вроде все, что должно получиться, на месте...
Теоретически эту функцию можно ускорить еще...
Допустил ошибку: function str_repeat ( string, multiplier ) =)
Не могу ручаться, но мне кажется, если изменить в оригинальном варианте
i++
на
++i
то будет заметный выигрыш в скорости.
по мелочи ускоренный вышеуказанный вариант:
оригинальную функцию можно упростить так:
или
Forum roksa pl
Отправить комментарий
Приветствуются комментарии:Для остальных вопросов и обсуждений есть форум.