note 98248 added to language.references

From: Date: Thu, 03 Jun 2010 23:05:47 +0000
Subject: note 98248 added to language.references
Groups: php.notes 
Request: Send a blank email to php-notes+get-169872@lists.php.net to get a copy of this message
Thanks midir and bytepirate for very valuable comments. After seeing the figures in the phparch article mentioned everything is clear now - PHP's references are broken by design regarding efficiency, kind of "copy on reference" :-) which results in useless data copying when you use some value in both static and "referenced" variables. See the following example <?php $iterations = 6000; $a = str_repeat("X", 6000); $starttime = microtime(true); for ($i = 0; $i <= $iterations; $i++) { $ar[$i] = $a; // there is actually no copying here! } echo (microtime(true) - $starttime) . " seconds expired\n"; $starttime = microtime(true); for ($i = 0; $i <= $iterations; $i++) { $item = &$ar[$i]; // "copy on reference" - the copying is done here! // remove the reference (assign it normally) and it will go fast! // it gives the same result if you pass it to function by reference } echo (microtime(true) - $starttime) . " seconds expired\n"; ?> The first for loop runs fast but the second one takes much much more. The contrary to what you'd expect! The first loop is optimized well by "copy on write" but the second one is a "copy on reference" trap and I think should be fixed in PHP. Bytepirate's example works even if we use the original variable instead of the new "referenced", and if we call an empty function: <?php $strlen=60000; $bstring=str_repeat("X",$strlen); $astring=&$bstring; // remove this line and it will go fast! $starttime=microtime(true); for($i=0;$i<=$strlen;$i++){ f($bstring); // 1ST CHANGE - even if you use the original value, it is also "poissoned"! // copying is done here, very slow } echo (microtime(true)-$starttime)." seconds expired\n"; function f($s) {} // make $s passed by reference and it will also go fast! ?> (This example looks still little artificial, but you can instead of "$astring=&$bstring" statement place the for loop into new "function g(&$bstring)", which is very real example!) This example shows that the "$astring=&$bstring" command is toxic also to the $bstring variable - every normal use of it (assignment, passing by value to function) will result in copying. But if you use it as a reference only then no copying will be done. CONCLUSION: 1) NEVER use the references as an optimization! It will go slower! 2) use references only if you must 3) if you use them, remember that every normal use (normal assignment, passing by value) of both the referenced and referencing variables will result in data copying! If you use them as references no copying is done. ---- Server IP: 69.147.83.197 Probable Submitter: 213.220.235.202 ---- Manual Page -- http://www.php.net/manual/en/language.references.php Edit -- https://master.php.net/note/edit/98248 Del: integrated -- https://master.php.net/note/delete/98248/integrated Del: useless -- https://master.php.net/note/delete/98248/useless Del: bad code -- https://master.php.net/note/delete/98248/bad+code Del: spam -- https://master.php.net/note/delete/98248/spam Del: non-english -- https://master.php.net/note/delete/98248/non-english Del: in docs -- https://master.php.net/note/delete/98248/in+docs Del: other reasons-- https://master.php.net/note/delete/98248 Reject -- https://master.php.net/note/reject/98248 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#169872) next »