Bug #34540 [Com]: dramatic count and strlen slow down on variable reference
| From: | sergio dot nalin at gmail dot com | Date: | Sun, 12 May 2013 16:25:18 +0000 |
| Subject: | Bug #34540 [Com]: dramatic count and strlen slow down on variable reference | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-178907@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=34540&edit=1
ID: 34540
Comment by: sergio dot nalin at gmail dot com
Reported by: php at vicaya dot com
Summary: dramatic count and strlen slow down on variable
reference
Status: Not a bug
Type: Bug
Package: Performance problem
Operating System: Linux 2.6.12
PHP Version: 4.4.0
Block user comment: N
Private report: N
New Comment:
May I ask why does PHP need to make a copy of the variable?
Shouldn't copy-on-write suffice to handle this?
strlen(), count(), etc aren't going to write anything to the variable and
therefore should not cause a copy (at least for performance's sake).
Previous Comments:
------------------------------------------------------------------------
[2005-09-18 22:54:21] php at vicaya dot com
Fair enough, as strlen and count is documented to accept a mixed var not a reference. But the
builtin functions like count and strlen should be able to handle reference efficiently. Why
it'd be so hard to do so? There're a lot of cases you want to use count and strlen on a
reference to variable. eg. you want to modify some huge array or string but you want to use count
and strlen first to find out the length...
Maybe it's not a language bug per se, But a limitation/problem of the interface of the builtin
functions like strlen and count.
------------------------------------------------------------------------
[2005-09-18 20:13:33] derick@php.net
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
In case you pass it by reference to the function, and then use the same variable as parameter to a
function that doesn\'t accept by reference, then PHP needs to make a copy of the array. In case
you do not pass by reference, in this case PHP doesn\'t have to copy the array because
it\'s internal refcounting mechanism is smart enough.
If you are just passing by reference to ensure PHP doesn\'t create a copy, then you\'re
doing things wrong. You should only pass by reference when you are actually modifying the array
inside the function.
------------------------------------------------------------------------
[2005-09-18 08:18:26] php at vicaya dot com
Description:
------------
There is a dramatic (talking about orders of magnitude here) slow down when use count or strlen on
referenced variables (including pass by reference and using the global keyword). strace shows
excessive brk and mremap activities in such cases.
If you use the foreach loop (commented out in the attached code) to count the elements, the version
using reference is faster. See attached code and benchmark for details.
# pass by value and count()
$ /usr/bin/time php passva.php
2.43user 0.30system 0:02.77elapsed 98%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+47193minor)pagefaults 0swaps
# pass by reference and count()
/usr/bin/time php passra.php
70.32user 14.52system 1:27.73elapsed 96%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+2982532minor)pagefaults 0swaps
# pass by value and foreach loop
$ /usr/bin/time php passva.php
127.99user 1.72system 2:13.97elapsed 96%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+276203minor)pagefaults 0swaps
# pass by reference and foreach loop
$ /usr/bin/time php passra.php
47.73user 0.37system 0:49.36elapsed 97%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+47194minor)pagefaults 0swaps
Reproduce code:
---------------
<?
# passva.php
for ($i = 0; $i < 1000000; ++$i) { $a[] = $i; }
for($i = 0 ; $i < 100 ; ++$i ) doit($a);
#function doit($arg) { $s = 0; foreach($arg as $i) { ++$s; } }
function doit($arg) { count($arg); }
?>
<?
# passra.php
for ($i = 0; $i < 1000000; ++$i) { $a[] = $i; }
for($i = 0 ; $i < 100 ; ++$i ) doit($a);
#function doit(&$arg) { $s = 0; foreach($arg as $i) { ++$s; } }
function doit(&$arg) { count($arg); }
?>
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=34540&edit=1