php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #48197 __call performs extra allocs
Submitted: 2009-05-08 20:43 UTC Modified: 2015-04-08 10:58 UTC
Votes:4
Avg. Score:4.8 ± 0.4
Reproduced:3 of 3 (100.0%)
Same Version:1 (33.3%)
Same OS:2 (66.7%)
From: rodricg at sellingsource dot com Assigned: dmitry (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 5.3.0RC2 OS: 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: rodricg at sellingsource dot com
New email:
PHP Version: OS:

 

 [2009-05-08 20:43 UTC] rodricg at sellingsource dot com
Description:
------------
When returning a value from __call (as compared to a non-dynamic method) extra memory is allocated.  This leads to performance degradation dependent on the size of the returned value.  

Hopefully this is a better description/example of bug #47525.


Reproduce code:
---------------
http://rodric.org/mem.phps

This script takes 3 arguments. ie.
mem.php <iterations> <method> <size>

See "Actual Result" for invocations.

Expected result:
----------------
Bytes allocated when using __call should be similar to not using __call.

When using __call the time taken should not degrade linearly as the size of the result value increases.

Actual result:
--------------
Change USE_ZEND_ALLOC to 1 and you will see that "magic" performs exactly <iterations> more allocs than "getStr".

Using __call:

USE_ZEND_ALLOC=0 valgrind php -n -d memory_limit=1024M mem.php 100 magic 1000000 2>&1 | pcregrep "Time|allocs"
Time: 1.5781
==25158== malloc/free: 19,564 allocs, 18,033 frees, 104,476,083 bytes allocated.

USE_ZEND_ALLOC=0 valgrind php -n -d memory_limit=1024M mem.php 100 magic 2000000 2>&1 | pcregrep "Time|allocs"
Time: 3.1066
==25161== malloc/free: 19,564 allocs, 18,033 frees, 205,476,083 bytes allocated.


Not Using __call:

USE_ZEND_ALLOC=0 valgrind php -n -d memory_limit=1024M mem.php 100 getStr 1000000 2>&1 | pcregrep "Time|allocs"
Time: 0.0280
==25181== malloc/free: 18,764 allocs, 17,233 frees, 4,444,183 bytes allocated.

USE_ZEND_ALLOC=0 valgrind php -n -d memory_limit=1024M mem.php 100 getStr 2000000 2>&1 | pcregrep "Time|allocs"
Time: 0.0281
==25183== malloc/free: 18,764 allocs, 17,233 frees, 5,444,183 bytes allocated.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-05-09 03:59 UTC] jani@php.net
Dmitry, can you please check this out..
 [2009-05-14 10:05 UTC] dmitry@php.net
I confirm the problem, however I'm not able to fix it in this moment.

Regular "user" functions are able to return zval** however internal functions (__call implemented through internal function) are able to return only zval*. As result we can't return pointer to the original zval* and need to separate it.
 [2015-04-08 10:58 UTC] dmitry@php.net
-Status: Assigned +Status: Closed
 [2015-04-08 10:58 UTC] dmitry@php.net
This seems to be fixed in PHP-5.6 and above.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Tue Jan 07 03:01:31 2025 UTC