Я читал о буферизации вывода в JavaScript здесь, и пытался разобраться в сценарии, который, по словам автора, был самым быстрым при печати от 1 до 1 000 000 на веб-странице. (Прокрутите вниз до заголовка «Сценарий выигрышного номера в миллион».) После небольшого изучения у меня возникло несколько вопросов:
(Я понимаю, что это, вероятно, CS101, но я один из тех проклятых хакеров-самоучок, и я надеялся извлечь выгоду из мудрости коллектива в этом вопросе. Спасибо!)



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я готов поспорить, что самая медленная вещь при печати 1-метровых чисел - это перерисовка страницы браузером, поэтому чем меньше раз вы вызываете document.write (), тем лучше. Конечно, это должно быть сбалансировано с большими конкатенациями строк (потому что они включают выделение и копирование).
Правильный размер буфера определяется экспериментальным путем.
В других примерах буферизация помогает выравниваться по естественным границам. вот несколько примеров
Согласование с естественными границами других систем часто может улучшить производительность.
Один из способов подумать об этом - это принять во внимание, что один вызов document.write () очень дорого обходится. Однако создание массива и объединение этого массива в строку - нет. Таким образом, уменьшение количества вызовов document.write () эффективно сокращает общее время вычислений, необходимое для записи чисел.
Буферы - это способ попытаться связать вместе две части работы с разными затратами.
Вычисление и заполнение массивов имеет небольшую стоимость для небольших массивов, большая ошибка - для больших массивов. document.write имеет большую постоянную стоимость независимо от размера записи, но масштабируется меньше o (n) для больших входных данных.
Таким образом, создание очереди для записи больших строк или их буферизация ускоряет общую производительность.
Кстати, хорошая находка по статье.
Так что этот сводил меня с ума, потому что я не думаю, что он действительно самый быстрый. Итак, вот мой эксперимент, с которым может играть каждый. Возможно, я написал это неправильно или что-то в этом роде, но похоже, что делать все сразу, а не использовать буфер, на самом деле более быстрая операция. Или, по крайней мере, в моих экспериментах.
<html>
<head>
<script type = "text/javascript">
function printAllNumberBuffered(n, bufferSize)
{
var startTime = new Date();
var oRuntime = document.getElementById("divRuntime");
var oNumbers = document.getElementById("divNumbers");
var i = 0;
var currentNumber;
var pass = 0;
var numArray = new Array(bufferSize);
for(currentNumber = 1; currentNumber <= n; currentNumber++)
{
numArray[i] = currentNumber;
if (currentNumber % bufferSize == 0 && currentNumber > 0)
{
oNumbers.textContent += numArray.join(' ');
i = 0;
}
else
{
i++;
}
}
if (i > 0)
{
numArray.splice(i - 1, bufferSize - 1);
oNumbers.textContent += numArray.join(' ');
}
var endTime = new Date();
oRuntime.innerHTML += "<div>Number: " + n + " Buffer Size: " + bufferSize + " Runtime: " + (endTime - startTime) + "</div>";
}
function PrintNumbers()
{
var oNumbers = document.getElementById("divNumbers");
var tbNumber = document.getElementById("tbNumber");
var tbBufferSize = document.getElementById("tbBufferSize");
var n = parseInt(tbNumber.value);
var bufferSize = parseInt(tbBufferSize.value);
oNumbers.textContent = "";
printAllNumberBuffered(n, bufferSize);
}
</script>
</head>
<body>
<table border = "1">
<tr>
<td colspan = "2">
<div>Number: <input id = "tbNumber" type = "text" />Buffer Size: <input id = "tbBufferSize" type = "text" /><input type = "button" value = "Run" onclick = "PrintNumbers();" /></div>
</td>
</tr>
<tr>
<td style = "vertical-align:top" width = "30%">
<div id = "divRuntime"></div>
</td>
<td width = "90%">
<div id = "divNumbers"></div>
</td>
</tr>
</table>
</body>
</html>