Re: PHP 4.0 Bug #7113: count and pointers

From: Date: Wed, 11 Oct 2000 00:16:45 +0000
Subject: Re: PHP 4.0 Bug #7113: count and pointers
References: 1 2  Groups: php.dev 
Request: Send a blank email to php-dev+get-34628@lists.php.net to get a copy of this message
Dhr. CaPS Cappert writes: > Now why would you do > $blah = count(&$data) > the '&' doesn't make sense here. The code above still > wouldn't make it make sense. count() doesn't modify, NO SENSE > in using it there. With due respect, I believe that you are at least partially mistaken. You might want to pass by reference for The Other Reason: avoiding having to pass an 8-10MB array on the function call. Granted, you'd either need to enable allow_call_time_pass_reference or mask out E_COMPILE_WARNING in php.ini, but it can be done, works, and makes sense. I am not, you should note, making any claims as to how future-proof the operation is. :) > This time difference I had can be achieved like this > $file = file("whatever"); > $data = &$file; > $count = count ($data); Ah. So you're saying that creating a second name for the same 8-10MB array and passing all that data (albeit by a different name) makes sense? References in PHP aren't pointers or references like in C. They are simply aliases. By creating a reference to the data, and then passing that reference, all you are doing is creating a new name for the same huge chunk of data, and then passing that data by its new name. However, when you pass by reference (and there does seem to be a difference in PHP between 'passing BY reference' and 'passing A reference'), you are passing only a reference to that data's entry in the symbol table--thereby skipping a potentially huge copy. Granted, PHP 4 has deprecated support for call-time pass-by-reference, so to get the code above to work, you would either need to enable allow_call_time_pass_by_reference or mask out E_COMPILE_WARNING in php.ini. In the current CVS of PHP 4, call-time pass-by-reference will work anyway, even though it'll spit a big warning at you telling you that it didn't work. By changing BYREF_ALLOW to BYREF_FORCE in count()'s function entry in basic_functions.c, I was able to get _all_ invocations of count() to pass by reference automatically, removing the need to use the deprecated syntax to get a reasonable speed out of the thing. I'm sure there is some deep subtle reason for this not being the default, since, as you mention, count() will never modify its argument and therefore one might as well pass by reference--especially given that the performance increase offered by doing so is at least a couple of orders of magnitude. > (Which seems like the PROPER way to do it.) > > This was on a binary file (A mp3 size 6.3mb) > Running on a Celly 366 / 128M > > --CaPS I've just tested both with a 13MB INBOX (straight ASCII) and a 6.5MB .mp3 and I get similar results: passing by reference (either by changing BYREF_ALLOW to BYREF_FORCE or by call-time pass-by-reference) results in the INBOX file getting counted 4 times in 0.01-0.5 seconds; using your method, 4 count()s take 6-7 seconds; and using normal pass-by-value, 4 counts() take 10-11 seconds. I will admit that there are things about the Zend-level reference passing that I do not understand, and I certainly do not understand why the ability to force call-by-reference has been deprecated (can someone explain that to me?). I do not understand why you are getting the timing results which you are getting. Perhaps there are deep magic reasons for all of these things. If you wish, I can send you the scripts with which I am testing this. -- +----------------------------------------------------------------+ |Torben Wilson <torben@php.net> Netmill iTech| |http://www.coastnet.com/~torben http://www.netmill.fi| |Ph: 1 250 383-9735 torben@netmill.fi| +----------------------------------------------------------------+

« previous php.dev (#34628) next »