Bug #66325 [Opn->Nab]: is_array argument is not passed by reference
| From: | laruence@php.net | Date: | Fri, 20 Dec 2013 03:23:00 +0000 |
| Subject: | Bug #66325 [Opn->Nab]: is_array argument is not passed by reference | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-183411@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=66325&edit=1
ID: 66325
Updated by: laruence@php.net
Reported by: ujvari at microsec dot hu
Summary: is_array argument is not passed by reference
-Status: Open
+Status: Not a bug
Type: Bug
Package: Arrays related
PHP Version: Irrelevant
Block user comment: N
Private report: N
New Comment:
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
Previous Comments:
------------------------------------------------------------------------
[2013-12-19 19:19:34] anon at anon dot anon
PHP variables are copy-on-write. They use low-level references everywhere internally. However, a
value cannot be referred to both byval and byref at the same time, so using references actually
makes it more likely that the value will need to be copied, which is what's happening in your
code. If you simply REMOVE every ampersand from your sample program, you will see the same high
performance from both functions.
Related: http://www.php.net/manual/en/features.gc.refcounting-basics.php.
------------------------------------------------------------------------
[2013-12-19 18:01:19] ujvari at microsec dot hu
Description:
------------
The is_array() function does not takes it's argument by reference, but copies it. When it takes
a large array as an argument and it is called this way many times (for example in a "for"
cycle) then it can take a huge time to run beacause of large amount of memory copies.
The same problem probably exists at other array related functions.
In PHP 5.3 and earlier you cound use is_array(&$array) to mitigate the performance bottleneck.
Since call-time pass-by-reference was removed in PHP 5.4 there is no way to do a workaround anymore.
Test script:
---------------
<?php
function delta($prefix, $t1) {
$t2 = microtime(true);
printf("%s %0.6f\n", $prefix, ($t2 - $t1) * 1000);
}
function &genarray() {
$a = array();
for($i = 0; $i < 10000; $i++) {
$a[] = $i;
}
return($a);
}
function noref(&$a) {
for($i = 0; $i < 10000; $i++) {
is_array($a);
}
}
function byref(&$a) {
for($i = 0; $i < 10000; $i++) {
is_array(&$a);
}
}
$a = &genarray();
$t1 = microtime(true);
noref($a);
delta("NoRef:", $t1);
$t3 = microtime(true);
byref($a);
delta("ByRef:", $t3);
?>
Expected result:
----------------
I expected that NoRef timing be (almost) equal to ByRef timing.
Actual result:
--------------
NoRef: 9246.673107
ByRef: 1.910925
NoRef is ~5000 times slower than ByRef.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=66325&edit=1