Я ищу способ вывода данных как можно большему числу клиентов, как можно быстрее и без задержек. Поэтому я подумал о том, чтобы разделить вывод предварительно сжатых данных на куски, чтобы браузеры клиента могли быстрее их распознать. Вот что я получил в коде для разделения выходных данных на 1500 байт (и я выбрал 1500, потому что это соответствует MTU Ethernet сервера).
<?php
$chunk="<about 7kb gzipped data>";
header("Content-length: ".strlen($chunk),true);
flush();
while (1){
$sz=strlen($chunk);
if ($sz > 1500){$sz=1500;}
echo substr($chunk,0,$sz);
flush();
$chunk=substr($chunk,$sz);
$sz=strlen($chunk);
if ($sz < 1500){break;}
}
echo $chunk;
flush();
?>
Есть ли способ, которым я могу сделать это без расчета длины строки так много раз? Я ищу в основном эквивалент того, что у меня есть, за исключением того, что он должен выполняться гораздо быстрее.
Если $chunk
не меняется во время выполнения сценария тогда нет необходимости рубить строку. Все, что это делает, это тратит память, выделяя несколько блоков.
PHP будет не освободить память, пока скрипт не завершится, и все строковые операции (такие как substr
) выделит новый буфер для своего результата. Это означает, что использование вашей памяти было бы на порядок выше 7 КБ для записи этого очень короткого объема данных.
Это было бы намного быстрее (меньше malloc
вызовы, которые являются дорогими) и более легкими в памяти (требуется чуть более 7 КБ памяти), чтобы просто записать каждый блок, извлекая их непосредственно из главной строки:
$chunk="<about 7kb gzipped data>";
$sz=strlen($chunk);
header("Content-length: ".$sz,true);
flush();
$pos=0;
while ($pos <= $sz){
echo substr($chunk,$pos,1500);
flush();
$pos += 1500;
}
Но, на самом деле, проверьте это, потому что я уверен, что много быстрее, потому что интерпретатор PHP очень эффективен в таких вещах, и ваш веб-сервер все равно будет выполнять довольно разумную буферизацию. Попытка обойти это часто проигрышная игра.
$chunk="<about 7kb gzipped data>";
echo $chunk;
Также обратите внимание, что PHP хранит длину строки в скрытом поле, так strlen
на самом деле не дорогая операция. Это дополнительные выделения памяти и частичный вывод, которые делают это медленным.
Других решений пока нет …