ID:               18367
 Updated by:       [EMAIL PROTECTED]
 Reported By:      [EMAIL PROTECTED]
 Status:           Bogus
 Bug Type:         Performance problem
 Operating System: All
 PHP Version:      4.2.1
 New Comment:

I've used Apache 1.3.26 and today's CVS of php. This test was done
across local network, which is very important for this test, because
your bechmark also includes network latency in it's test. Meaning that
if you do this test over a slow connection the timings would reflect
that fact.
Because the 2nd timing won't be taken until the printed data is
recieved by the browser on the other end.
I've also done more accurate tests using php-cli on the console where
there is network overhead.

My benchmark resulted in the following timings for printing
250000 byte long string 10000 times.
PHP - 0.824s
Perl - 1m2.245s

Ignore the manual comment, that is automatically added by the bug
tracking system.


Previous Comments:
------------------------------------------------------------------------

[2002-09-22 17:56:09] [EMAIL PROTECTED]

> 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?

------------------------------------------------------------------------

[2002-09-22 16:35:38] [EMAIL PROTECTED]

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] [EMAIL PROTECTED]

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] [EMAIL PROTECTED]

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

Reply via email to