ID: 40261
User updated by: thuejk at gmail dot com
-Summary: Extremely slow data handling in specific situation
Reported By: thuejk at gmail dot com
Status: Open
Bug Type: Performance problem
Operating System: Linux
PHP Version: 5.2.0
New Comment:
Ok, after a good deal of work I actually tracked down the problem to
fragmentation in your memory management.
This understanding enabled me to construct a simpler test case. Note
that the problem is unrelated to database function, and this new
testcase does not require any database.
<?php
//According to my calculations, setting $num=18000000 should make this
script take ~one year.
$num = 100000;
$a = Array();
for ($i=0; $i<$num; $i++) {
$a[$i] = Array(1);
}
/* The underlying memory now looks something like
* row structure
* row value
* row structure
* ...
*/
$b = Array();
for ($i=0; $i<$num; $i++) {
$b[$i] = $a[$i][0];
}
/* The b rows are allocated
*
* Though I haven't checked it in the code, I have reason to believe
* that the values inserted into the b rows are pointers to the same
* memory allocated for the values in the a rows
*/
unset($a);
/* The a rows are unallocated, but the values are still references from
$b, so the memory map looks something like
* row value
* free_block
* row_value
* free_block
* ...
*
* repeated $num times.
*/
/* Now, for each memory allocation for a row, PHP runs through all
* free blocks checking for a best fit. Since there are $num free
* blocks, this takes time. This is done by the function
* _zend_mm_alloc_int in PHP 5.2.0 Zend/zend_alloc.c :
*
* end = &heap->free_buckets[0];
* for (p = end->next_free_block; p != end; p = p->next_free_block) {
* size_t s = ZEND_MM_FREE_BLOCK_SIZE(p);
* if (s > true_size) {
* if (s < best_size) { // better fit
* best_fit = p;
* best_size = s;
* }
* } else if (s == true_size) {
* // Found "big" free block of exactly the same size
* best_fit = p;
* goto zend_mm_finished_searching_for_block;
* }
* }
*/
$c = Array();
for ($i=0; $i<$num; $i++) {
$c[$i] = 1;
}
?>
Previous Comments:
------------------------------------------------------------------------
[2007-01-28 01:52:37] thuejk at gmail dot com
On second though, black boxes are not good for testing. A simpler timer
added...
------------------------------------------------------------------------
[2007-01-28 01:47:01] thuejk at gmail dot com
I have made it a bit shorter.
I left the DebugStats class in, it is useful. Just treat it as a black
box. I can garantie that the two calls into it does not account for the
8 seconds performance problem...
------------------------------------------------------------------------
[2007-01-28 01:30:33] [EMAIL PROTECTED]
Could please modify the script, so that it would be _short_ but
complete?
------------------------------------------------------------------------
[2007-01-28 01:25:13] thuejk at gmail dot com
I added the requested changes to the linked file
http://thuejk.dk/test.php.txt
------------------------------------------------------------------------
[2007-01-28 01:15:25] [EMAIL PROTECTED]
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves.
A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external
resources such as databases, etc. If the script requires a
database to demonstrate the issue, please make sure it creates
all necessary tables, stored procedures etc.
Please avoid embedding huge scripts into the report.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
http://bugs.php.net/40261
--
Edit this bug report at http://bugs.php.net/?id=40261&edit=1