Bug #66325 [Com]: is_array argument is not passed by reference

From: Date: Thu, 19 Dec 2013 19:19:35 +0000
Subject: Bug #66325 [Com]: is_array argument is not passed by reference
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-183403@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 Comment by: anon at anon dot anon Reported by: ujvari at microsec dot hu Summary: is_array argument is not passed by reference Status: Open Type: Bug Package: Arrays related PHP Version: Irrelevant Block user comment: N Private report: N New Comment: 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. Previous Comments: ------------------------------------------------------------------------ [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

« previous php.bugs (#183403) next »