以尽可能快的速度推出分块字节


pushing out chunked bytes as fast as possible

我正在寻找一种将数据输出到尽可能多的客户端的方法,尽可能快且无延迟。因此,我考虑将预压缩的数据输出划分为块,以便客户端的浏览器能够更快地识别数据。到目前为止,我在代码中将输出划分为1500字节的块(我选择1500是因为它与服务器的以太网MTU相匹配)。

<?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)都会为其结果分配一个新的缓冲区。这意味着,要写出这么短的数据量,你的内存使用量将比7kb高出一个数量级。

通过直接从主字符串中提取每个块来写入每个块会更快(更少的malloc调用,这很昂贵),在内存上也更容易(只需要超过7kb的内存)

$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解释器在这方面非常高效,而且你的web服务器无论如何都会做相当智能的缓冲。试图解决它往往是一场失败的游戏。

$chunk="<about 7kb gzipped data>";
echo $chunk;

还要注意,PHP将字符串的长度存储在一个隐藏字段中,因此strlen实际上并不是一个昂贵的操作。正是额外的内存分配和分块输出使速度变慢。