php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #50351 performance regression handling objects, ten times slower in 5.3 than in 5.2
Submitted: 2009-12-01 12:53 UTC Modified: 2009-12-07 08:17 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: rlillack at yasni dot de Assigned: dmitry (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 5.3.1 OS: 64/32bit linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: rlillack at yasni dot de
New email:
PHP Version: OS:

 

 [2009-12-01 12:53 UTC] rlillack at yasni dot de
Description:
------------
PHP 5.3 did indeed introduce many performance improvements, but we 
spotted a rather hard regression with handling a large amount of 
objects that are allocated at the same time.

Running the following test case on one of our web servers yield this 
result with a vanilla build of 5.2.11:

time: 1.28 secs, memory usage 376.48 MiB.

and this with 5.3.1:

time: 13.44 secs, memory usage 400.62 MiB.

(command line in both cases: PREFIX/bin/php -d memory_limit=2G 
testcase.php)

The regression at least since the PHP 5.3 release candidates.

Both were fresh build straight from the tarball, No extensions, etc. 
Opcode caches do not help. --with-zend-vm does not help.


Reproduce code:
---------------
<?php
$start = microtime(TRUE);

$a = array();
foreach (range(1, 1000000) as $i) {
    $a []= new StdClass;
}

printf("time: %s secs, memory usage %s MiB.\n",
       number_format(microtime(TRUE) - $start, 2),
       number_format(memory_get_usage() / 1024 / 1024, 2));


Expected result:
----------------
PHP 5.3.1 should not be any slower than 5.2.11 is. :)

Actual result:
--------------
PHP 5.3.1 is ten times slower in this test case.

One of our apps does only handle 1/4th queries/s with 5.3 on a 
production server.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-12-01 13:37 UTC] jani@php.net
[jani@localhost ~]$ src/build/php_5_2/sapi/cli/php -n -d memory_limit=2G t.php
time: 4.10 secs, memory usage 371.39 MiB.
[jani@localhost ~]$ src/build/php_5_3/sapi/cli/php -n -d memory_limit=2G t.php
time: 25.97 secs, memory usage 383.46 MiB.

 [2009-12-01 13:38 UTC] jani@php.net
My results were done with i686..
 [2009-12-01 13:48 UTC] rlillack at yasni dot de
This seems to be related to the new cyclic garbage collector trying to 
free memory after each allocation?!

A rather simple workaround is to insert gc_disable() before and gc_enable() after entering the loop.
 [2009-12-01 14:46 UTC] jani@php.net
See also bug #48781 (propably related as well)
 [2009-12-02 08:42 UTC] notarealemail at nodomain dot com
Simply changing the loop from

foreach (range(1, 1000000) as $i)

to

for ( $i = 0; $i < 1000000; $i++ )

Makes php 5.3.1 (win xp vc9 nots cli) run "normal", even faster than 5.2.11 (same configuration).

Performance (php 5.3.1):

time: 8.23 secs, memory usage 219.38 MiB. (original loop)
time: 0.91 secs, memory usage 219.39 MiB. (modified loop)
time: 0.72 secs, memory usage 219.38 MiB. (modified loop, GC disabled)

Tested on a E8400 3GHz.
 [2009-12-02 08:59 UTC] jani@php.net
Not exactly faster but better than with foreach():

[jani@localhost ~]$ php -d memory_limit=2G t.php
time: 2.73 secs, memory usage 371.39 MiB.
[jani@localhost ~]$ src/build/php_5_3/sapi/cli/php -d memory_limit=2G t.php
time: 3.05 secs, memory usage 383.46 MiB.


 [2009-12-02 09:11 UTC] notarealemail at nodomain dot com
Sorry, forgotten a benchmark:

time: 0.90 secs, memory usage 219.38 MiB. (original loop, GC disabled)

So the problem seems more related to foreach+array+garbage collector than class allocation
 [2009-12-02 09:59 UTC] rlillack at yasni dot de
It has to do something with object allocation because the problem does 
NOT occur with this loop:

foreach (range(1, 1000000) as $i) {
    $a []= array($i);
}
 [2009-12-02 12:10 UTC] dmitry@php.net
The reason of slowdown is Garbage Collector. I'll take a look into it.
 [2009-12-07 08:14 UTC] svn@php.net
Automatic comment from SVN on behalf of dmitry
Revision: http://svn.php.net/viewvc/?view=revision&revision=291807
Log: Fixed bug #50351 (performance regression handling objects, ten times slower in 5.3 than in 5.2. foreach statement should not initiate GC)
 [2009-12-07 08:17 UTC] dmitry@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sat Feb 01 07:01:31 2025 UTC