#18367 [Bgs]: Echoing long strings unexpectedly slow
| From: | van dot binsbergen at taktik dot ch | Date: | Sun, 22 Sep 2002 22:56:09 +0000 |
| Subject: | #18367 [Bgs]: Echoing long strings unexpectedly slow | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-20056@lists.php.net to get a copy of this message | ||
ID: 18367
User updated by: van.binsbergen@taktik.ch
Reported By: van.binsbergen@taktik.ch
Status: Bogus
Bug Type: Performance problem
Operating System: All
PHP Version: 4.2.1
New Comment:
> I've tried the suggested test and did not see any
> significant slowdown you've mentioned.
Did you really test with a server which which is in a
significant distance to your client machine?
And if so, which PHP and Apache Version did you use?
I mean, I didn't invent this story, you know. Neither did
the other users who faced this thing. I was just trying to
track down the reason. Although I do not understand much of
the interna it seems very likely to me that the reason sits
in php OR in apache OR in the playing together of both.
> There is one thing however, that may have skewed the
> benchmark towards Perl in your initial code. In Perl
> you seperate the text with a space, while in
> PHP you use a new line.
Sorry for this negligence, I tested in fact both variants
in both systems and it wasn't any difference.
PS: I do not understand your hint to the manual. If the
manual says something about this, can you please point me
to the exact location?
Previous Comments:
------------------------------------------------------------------------
[2002-09-22 16:35:38] iliaa@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to
report
a bug at http://bugs.php.net/how-to-report.php
I've tried the suggested test and did not see any significant slowdown
you've mentioned. Infact the benchmarks came about the same. There is
one thing however, that may have skewed the benchmark towards Perl in
your initial code. In Perl you seperate the text with a space, while in
PHP you use a new line.
------------------------------------------------------------------------
[2002-08-15 09:10:22] van.binsbergen@taktik.ch
Hi team!
Was there any progress regarding this thing? Please tell me
if you need more info. Thank you for your attention.
Urs
------------------------------------------------------------------------
[2002-07-16 09:27:55] van.binsbergen@taktik.ch
This is a follow-up to http://bugs.php.net/bug.php?id=18029
(I can't reach the author of this bug, so I will do it this
way). 18029 is in status "bogus", but I don't think this is
correct. In my opinion it is buggy behaviour of either PHP
or apache or both in combination. Please read the following
to see why I think this can and has to be changed.
What I noticed on my system:
Redhat Linux 7.2 (Kernel 2.4.7-10)
Apache/1.3.26 (Unix) PHP/4.2.1 mod_ssl/2.8.10 OpenSSL/
0.9.6b
resp. Apache/1.3.26 (Unix) PHP/4.2.0 mod_ssl/2.8.10
OpenSSL/0.9.6b
Outputting a string of x characters length takes 2
milliseconds.
Outputting a string of x+1 characters length takes 340
milliseconds.
x is a number between 12000 and 15000.
It does not matter whether I use echo, print, print_r or
whatever to output the string.
When I split the string in smaller parts and output the
results separately, everything is normal.
The timeout occurs if my browser is remote (ping-time about
200ms). This happens NOT, if my browser is in a LAN or
local with the server, i.e. very close. The hint to TCP/IP
window size (Nagle Algorithm) given by Ron Kuris to Shawn
(owner of bug 18029) matches with this and the above
observations. Execution of the Script does not continue
before the ACK from the client for the first packet is
received. This means that in scripts working with long
strings the execution time of the script depends on the
ping-time between the server and the client, and the
duration of the idle time goes up together with the length
of the string, i.e. a roundtrip is made for each multiple
of the window size.
I have positive reports of this from four systems, amongst
them PHP 4.2.0 und 4.2.1; Apache 1.3.23, 1.3.24 and 1.3.26;
OS Redhat, Cobalt and Windows 2000. I have 5 negative
reports, but maybe all false negative because they were
tested locally.
Below is a test php script that can be used to verify this.
There is also an equivalent perl script. I used it on the
same host as a CGI-Script and found everything works fine
there.
I might be wrong of course, but I think this thing has to
be treated as a bug because
1) it should be avoided
2) it can be avoided
Please let me tell you why:
1)
- There is growing number of modern PHP applications
depending on the possibility of flawlessly outputting large
strings. PEAR Cache for instance is affected, but template
processors and XML/XSL applications as well. Of course
these applications could all care themselves about
splitting their output in smaller chunks, but this is very
inefficient.
- Although there is no additional CPU load, the number of
running httpd-processes is kept high - for nothing. I don't
know whether this is actually bad, but it sure is not very
cool.
- Clients have a bad response time although the server and
network performance is good.
2)
- The fact that a Perl CGI script (see below) can do the
same thing without any problems shows imo that it is
possible in some way to avoid these roundtrips! I have to
admit that I have no idea of the apache/php interna, but I
would be very glad if someone of the experts had a look at
this.
Thank you in advance!
Urs
<?php
/**
Long string performance behaviour test
*/
// ------ small Benchmark suite (as in in perl's Benchmark)
---------
class Benchmark {
var $time = 0;
function Benchmark() {
$mt = microtime();
$a = explode(" ",$mt);
$t = $a[0] + $a[1];
$this->time = round(1000 * $t);
}
}
function timestr($ms) {
return sprintf("%01.2f", $ms/1000) . " seconds";
}
function timediff($b1, $b2) {
$ms = ($b1->time - $b2->time);
return $ms;
}
// ------ test procedure ---------
// prepare
($len = $_GET[l]) || ($len = 12905);
$loop = floor($len / 5);
$rest = $len % 5;
$rlen = 5 * $loop;
$str = "";
$t0 = new Benchmark;
// generate the long string
for($i=0; $i<=$loop; $i++) {
$str = $str . "1234";
$str .= "\n";
}
$str .= str_repeat(".",$rest);
// report
$t1 = new Benchmark;
$report .= "<h1>Long string performance behaviour test</
h1>";
$report = "\n<br>\n<br>Generated a string with $len
characters"
. " (use ?l=12345 in the URI to override)";
$report .= "\n<br>(took me " . timestr(timediff($t1, $t0))
. ")";
// print the long string
print $str;
// report again
$t2 = new Benchmark;
$report .= "\n<br>Time to output string:
".timestr(timediff($t2, $t1));
print $report;
?>
test.pl:
#! /usr/bin/perl
use CGI qw(:standard);
use Benchmark;
print header();
# prepare
($len = param("l")) || ($len = 50000);
$loop = int($len / 5);
$rest = $len % 5;
$rlen = 5 * $loop;
$str = "";
$t0 = new Benchmark;
# generate the long string
for($i=0; $i<=$loop; $i++)
{
$str = $str . "1234 ";
}
# report
$t1 = new Benchmark;
$report .= "<h1>Long string performance behaviour test</
h1>";
$report = "\n<br>\n<br>Generated a string with $len
characters"
. " (use ?l=12345 in the URI to override)";
$report .= "\n<br>(took me " . timestr(timediff($t1, $t0))
. ")";
# print the long string
print $str;
# report again
$t2 = new Benchmark;
$report .= "\n<br>Time to output string:
".timestr(timediff($t2, $t1));
print $report;
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=18367&edit=1