ID: 47487 Updated by: johan...@php.net Reported By: basant dot kukreja at gmail dot com -Status: Open +Status: Assigned Bug Type: Streams related Operating System: Solaris 10 PHP Version: 5.2.9RC3 -Assigned To: +Assigned To: lbarnaud New Comment:
Arnaud, you fixed the other issue, can you please take a look at this regression. Thanks. Previous Comments: ------------------------------------------------------------------------ [2009-02-24 09:10:00] basant dot kukreja at gmail dot com Sorry, file name was missing from the patch : --- a/php-5.2.9RC3/main/streams/streams.c Sun Feb 22 19:57:30 2009 -0800 +++ b/php-5.2.9RC3/main/streams/streams.c Tue Feb 24 00:50:21 2009 -0800 @@ -1251,6 +1253,11 @@ * 2K). */ if (php_stream_stat(src, &ssbuf) == 0 && ssbuf.sb.st_size > 0) { max_len = ssbuf.sb.st_size + step; + if (max_len > src->readbuflen) { + src->readbuflen = max_len; + src->readbuf = perealloc(src->readbuf, src->readbuflen, + src->is_persistent); + } } else { max_len = step; } ------------------------------------------------------------------------ [2009-02-24 08:59:45] basant dot kukreja at gmail dot com There might be several possible way to fix it. Here is one alternative which requires more memory but avoid includes : @@ -1251,6 +1253,11 @@ * 2K). */ if (php_stream_stat(src, &ssbuf) == 0 && ssbuf.sb.st_size > 0) { max_len = ssbuf.sb.st_size + step; + if (max_len > src->readbuflen) { + src->readbuflen = max_len; + src->readbuf = perealloc(src->readbuf, src->readbuflen, + src->is_persistent); + } } else { max_len = step; } -------------------------------- The above patch though have single alloc but still require large memory allocation. Before this patch too, large memory is allocated but by several folds. Before PR http://bugs.php.net/bug.php?id=44607 was fixed, php only required 8KB memory at a time and no reallocs happened. ------------------------------------------------------------------------ [2009-02-24 08:52:57] basant dot kukreja at gmail dot com Description: ------------ After bug 44607 is fixed, php_stream_fill_read_buffer does many reallocs for medium to large file (e.g 60KB) Before the bug 44607 was fixed, php_stream_fill_read_buffer returns after single read so there was no reallocs. But after the fix, it keeps reading until the entire file is read. Reproduce code: --------------- If we add a printf in php_stream_fill_read_buffer function like : while (stream->writepos - stream->readpos < (off_t)size) { size_t justread = 0; size_t toread; /* grow the buffer if required * TODO: this can fail for persistent streams */ if (stream->readbuflen - stream->writepos < stream->chunk_size) { stream->readbuflen += stream->chunk_size; fprintf(stderr, "php_stream_fill_read_buffer :reallocating %d\n", stream->readbuflen); stream->readbuf = perealloc(stream->readbuf, stream->readbuflen, stream->is_persistent); } Then for a php script which includes 60KB html file, following is printed. stderr: php_stream_fill_read_buffer :reallocating 8192 stderr: php_stream_fill_read_buffer :reallocating 16384 stderr: php_stream_fill_read_buffer :reallocating 24576 stderr: php_stream_fill_read_buffer :reallocating 32768 stderr: php_stream_fill_read_buffer :reallocating 40960 stderr: php_stream_fill_read_buffer :reallocating 49152 stderr: php_stream_fill_read_buffer :reallocating 57344 Expected result: ---------------- Less number of memcpy. Because of the reallocs, huge amount of memcpy happens. This happened after php-5.2.6. http://bugs.php.net/bug.php?id=44607 Actual result: -------------- Degrade in performance. ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=47487&edit=1