我有一个脚本,用一个字符串($ content)构建我的网页,然后将其回显给用户.
我的脚本看起来像这样:
$time1= microtime(true);
$content = create_content();
$content_time=(microtime(true)-$time1)
$time = microtime(true);
echo $content;
$echo_time = (microtime(true)-$time);
Run Code Online (Sandbox Code Playgroud)
现在$ content_time总是低于0.5s,所以没问题.然而,每天几次$ echo_time远远超过一秒,甚至可以达到15秒.内容不是很大,大约10-20kb,发生这种情况的时间是完全随机的,所以它不是在忙碌的时候,甚至发生在半夜.
有人知道那可能是什么吗?
编辑该站点托管在(远程)专用服务器上,仅托管此站点.有一个数据库涉及,但就像我说$ content_time远低于1秒,所以这个功能的作用不能是延迟.
当我的网站时间超过一定值(比如5s)时,我会记录下来.甚至Googlebots似乎有时会遇到这些问题,所以我认为他们不会使用拨号连接:)
Ray*_*Ray 10
让我们缩小问题范围,并考虑一些事情......
在问题中,你表明你正在回应10-15kb.这是一个很大的数量,无论它如何缓冲输出 - 记住php是单线程,一旦你刷新你的缓冲区,你必须等待所有输出通过shell或HTTP发生在脚本继续之前.在继续回声之前,它最终必须刷新内部缓冲区.在没有回声的冲洗开销的情况下获得好时光
尝试更换
$time = microtime(true);
echo $content;
$echo_time = (microtime(true)-$time);
Run Code Online (Sandbox Code Playgroud)
同
ob_start();
$time = microtime(true);
echo $content;
$echo_time = (microtime(true)-$time);
ob_clean();
Run Code Online (Sandbox Code Playgroud)
这将回显缓冲区,但实际上并没有通过HTTP或其他任何东西吐出来.这应该给你echo命令的'真实'时间,而不用担心发送缓冲区中的内容.
如果echo_time缩小,您可以通过缓冲尽可能地解决传输问题.
如果echo_time仍然很大,你需要开始深入研究PHP C代码.
无论哪种方式,您都可以更接近找到问题和解决方案
来自http://wonko.com/post/seeing_poor_performance_using_phps_echo_statement_heres_why
这个旧的错误报告可能会有所启发.简而言之,使用echo将大字符串发送到浏览器会导致可怕的性能,因为Nagle算法会使数据被缓冲以通过TCP/IP进行传输.
解决方案?一个简单的三行函数,在回显它们之前将大字符串拆分成较小的块:
function echobig($string, $bufferSize = 8192) {
$splitString = str_split($string, $bufferSize);
foreach($splitString as $chunk) { echo $chunk; }
}
Run Code Online (Sandbox Code Playgroud)
使用缓冲区大小,看看哪种方式最适合您.我发现8192,除了是一个很好的圆形数字,似乎是一个很好的大小.某些其他价值观也有效,但经过几分钟的修补后,我无法辨别出一种模式,显然有一些数学在工作,我不想试图弄明白.
顺便说一下,当使用PHP的输出控制功能(ob_start()和朋友)时,性能也会发生.
在OPs发表评论说他已经尝试了这个,我在PHP.net上发现了以下内容,表明str_split也可能浪费资源,并且可以通过使用以下代码进一步优化echobig功能:
function echobig($string, $bufferSize = 8192) {
// suggest doing a test for Integer & positive bufferSize
for ($chars=strlen($string)-1,$start=0;$start <= $chars;$start += $bufferSize) {
echo substr($string,$start,$buffer_size);
}
}
Run Code Online (Sandbox Code Playgroud)
您是否尝试过使用CLI而不是Apache运行脚本?