Just came across something that triggered a bit of performance testing. One can cast objects to arrays and vice-versa in PHP. So, in common.inc, we have a function called object2array() that loops through an object and makes it into an array. Is that faster than the equivalent function using a cast (array) operator? No. In fact, it's about 2.4 times slower. However, both are very fast for an object with 26 elements. Here's the benchmark: 10000 'object2array' calls took 3.04 seconds. The average was 0.00030442 seconds per call. 10000 'better' calls took 1.27 seconds. The average was 0.00012693 seconds per call. Here are the tested functions: function object2array($object) { if (is_object($object)) { foreach ($object as $key => $value) { $array[$key] = $value; } } else { $array = $object; } return $array; } function better($object) { if (is_object($object)) { $array = (array) $object; } else { $array = $object; } return $array; } Worth a patch? ..chrisxj
On 14 Dec 2005, at 04:53, Chris Johnson wrote:
So, in common.inc, we have a function called object2array() that loops through an object and makes it into an array. Is that faster than the equivalent function using a cast (array) operator? No. In fact, it's about 2.4 times slower. However, both are very fast for an object with 26 elements. Here's the benchmark:
Worth a patch?
Definitely! It's a lot faster and less code. Keeping looking for improvements Chris! -- Dries Buytaert :: http://www.buytaert.net/
I seem to recall someone suggesting this before, and the problem was that the casting method didn't scale to nested objects and arrays. It should be in the issue archive, somewhere. :-) On Tuesday 13 December 2005 09:53 pm, Chris Johnson wrote:
Just came across something that triggered a bit of performance testing. One can cast objects to arrays and vice-versa in PHP.
So, in common.inc, we have a function called object2array() that loops through an object and makes it into an array. Is that faster than the equivalent function using a cast (array) operator? No. In fact, it's about 2.4 times slower. However, both are very fast for an object with 26 elements. Here's the benchmark:
10000 'object2array' calls took 3.04 seconds. The average was 0.00030442 seconds per call.
10000 'better' calls took 1.27 seconds. The average was 0.00012693 seconds per call.
Here are the tested functions:
function object2array($object) { if (is_object($object)) { foreach ($object as $key => $value) { $array[$key] = $value; } } else { $array = $object; } return $array; }
function better($object) { if (is_object($object)) { $array = (array) $object; } else { $array = $object; } return $array; }
Worth a patch?
..chrisxj
-- Larry Garfield AIM: LOLG42 larry@garfieldtech.com ICQ: 6817012 "If nature has made any one thing less susceptible than all others of exclusive property, it is the action of the thinking power called an idea, which an individual may exclusively possess as long as he keeps it to himself; but the moment it is divulged, it forces itself into the possession of every one, and the receiver cannot dispossess himself of it." -- Thomas Jefferson
OK, I just checked and I was wrong. I was thinking of array2object(), which was discussed here: http://lists.drupal.org/archives/development/2005-09/msg01015.html I'm not sure if there are edge cases that would affect object2array as well as array2object. If not, then yay for performance improvements. *crawls back under his rock* On Tuesday 13 December 2005 11:47 pm, Larry Garfield wrote:
I seem to recall someone suggesting this before, and the problem was that the casting method didn't scale to nested objects and arrays. It should be in the issue archive, somewhere. :-)
On Tuesday 13 December 2005 09:53 pm, Chris Johnson wrote:
Just came across something that triggered a bit of performance testing. One can cast objects to arrays and vice-versa in PHP.
So, in common.inc, we have a function called object2array() that loops through an object and makes it into an array. Is that faster than the equivalent function using a cast (array) operator? No. In fact, it's about 2.4 times slower. However, both are very fast for an object with 26 elements. Here's the benchmark:
10000 'object2array' calls took 3.04 seconds. The average was 0.00030442 seconds per call.
10000 'better' calls took 1.27 seconds. The average was 0.00012693 seconds per call.
Here are the tested functions:
function object2array($object) { if (is_object($object)) { foreach ($object as $key => $value) { $array[$key] = $value; } } else { $array = $object; } return $array; }
function better($object) { if (is_object($object)) { $array = (array) $object; } else { $array = $object; } return $array; }
Worth a patch?
..chrisxj
-- Larry Garfield AIM: LOLG42 larry@garfieldtech.com ICQ: 6817012 "If nature has made any one thing less susceptible than all others of exclusive property, it is the action of the thinking power called an idea, which an individual may exclusively possess as long as he keeps it to himself; but the moment it is divulged, it forces itself into the possession of every one, and the receiver cannot dispossess himself of it." -- Thomas Jefferson
Chris Johnson wrote:
Just came across something that triggered a bit of performance testing. One can cast objects to arrays and vice-versa in PHP.
So, in common.inc, we have a function called object2array() that loops through an object and makes it into an array. Is that faster than the equivalent function using a cast (array) operator? No. In fact, it's about 2.4 times slower. However, both are very fast for an object with 26 elements. Here's the benchmark:
10000 'object2array' calls took 3.04 seconds. The average was 0.00030442 seconds per call.
10000 'better' calls took 1.27 seconds. The average was 0.00012693 seconds per call.
Test out 10k calls to get_object_vars(). I've been running Drupal for a few months with a version of object2array() to see if the array handling is ever used: function object2array($object) { if (is_object($object)) { foreach ($object as $key => $value) { $array[$key] = $value; } } else { trigger_error('Watch yer type!!'); $array = $object; } return $array; } I haven't run into object2array being called with anything that isn't an object yet. -- Neil Drumm http://delocalizedham.com/
As it should be. It never even occurred to me to pass anything but an object to object2array(). On 12/14/05, Neil Drumm <drumm@delocalizedham.com> wrote:
I haven't run into object2array being called with anything that isn't an object yet.
Original results, with current Drupal object2array():
10000 'object2array' calls took 3.04 seconds. The average was 0.00030442 seconds per call.
With object2array() rewritten to remove loop and just cast the object to an array (i.e. $array = (array) $object, but otherwise unchanged function:
10000 'better' calls took 1.27 seconds. The average was 0.00012693 seconds per call.
Neil Drumm wrote:
Test out 10k calls to get_object_vars().
Because he has never seen object2array() called with anything but an object. Interesting idea. So I rewrote object2array() and better() like this: function object2array($object) { return get_object_vars($object); } function better($object) { return (array) $object; } And here are the results: 10000 'object2array' calls took 1.14 seconds. The average was 0.00011444 seconds per call. 10000 'better' calls took 1.05 seconds. The average was 0.00010478 seconds per call. So get_object_vars() is definitely faster than what we have now, but casting appears to be slightly faster still. Probably saving an interpreted function call and value return is the whole savings, as the internal C code for get_object_vars() and the cast are probably one and the same. Best of all, if someone does pass an array, casting an array to an array is a no-op, and the function still works the same. I will roll a patch today. ..chrisxj
Chris Johnson wrote:
Interesting idea. So I rewrote object2array() and better() like this:
function object2array($object) { return get_object_vars($object); }
function better($object) { return (array) $object; }
Why do we even need these one-line functions? Can't the calling code just do the casting? -Neil -- Neil Drumm http://delocalizedham.com/
On Wed, Dec 14, 2005 at 12:32:27PM -0800, Neil Drumm wrote:
Chris Johnson wrote:
Interesting idea. So I rewrote object2array() and better() like this:
function object2array($object) { return get_object_vars($object); }
function better($object) { return (array) $object; }
Why do we even need these one-line functions? Can't the calling code just do the casting?
I just finished posting the same thought in a comment on the issue[0]. Seems like a good idea to me... Extraneous function calls are bad. Thanks, -- Keegan Quinn <keegan@thebasement.org> CEO, Producer the basement productions http://www.thebasement.org [0] http://drupal.org/node/41169
Neil Drumm wrote:
Chris Johnson wrote:
Interesting idea. So I rewrote object2array() and better() like this:
function object2array($object) { return get_object_vars($object); }
function better($object) { return (array) $object; }
Why do we even need these one-line functions? Can't the calling code just do the casting?
not always. there are contexts in which function is legal but a cast is not. if anyone tries to change all the calls to these objects they will run into this.
Moshe Weitzman wrote:
Neil Drumm wrote:
Why do we even need these one-line functions? Can't the calling code just do the casting?
not always. there are contexts in which function is legal but a cast is not. if anyone tries to change all the calls to these objects they will run into this.
Hmm. That certainly could be, although I am unable to imagine such an instance. In my quick grep through the repositories, I'm not seeing any that cannot be changed. Can you give an example where a cast could not be used? ..chrisxj
Neil Drumm wrote:
Chris Johnson wrote:
Interesting idea. So I rewrote object2array() and better() like this:
function object2array($object) { return get_object_vars($object); }
function better($object) { return (array) $object; }
Why do we even need these one-line functions? Can't the calling code just do the casting?
-Neil
Yes, the calling code can be changed. It's just a much bigger patch, and documentation change. I'd like to see this change go through a beta release as-is to make sure there aren't any odd cases where it doesn't work. My test site works perfectly, but this seems like one of those places one would most likely trip over a bug or unexpected intended behavior in PHP itself. Undoing a few lines of code in common.inc is a lot easier than removing all the changes to the hundreds of calls throughout core and contrib. If it works fine in wide usage, I'll change all the core and contrib code to just use casting and suggest the documentation changes, too. ..chrisxj
I just did the same tests on the inverse routine, array2object() versus cast (object). The cast appears to be 4 times faster: 10000 'array2object' calls took 4.38 seconds. The average was 0.00043776 seconds per call. 10000 'cast object' calls took 1.05 seconds. The average was 0.00010541 seconds per call. Rolling more patches. See Issue #41169 (http://drupal.org/node/41169).
On Wed, Dec 14, 2005 at 12:48:07PM -0600, Chris Johnson wrote:
I just did the same tests on the inverse routine, array2object() versus cast (object). The cast appears to be 4 times faster:
10000 'array2object' calls took 4.38 seconds. The average was 0.00043776 seconds per call.
10000 'cast object' calls took 1.05 seconds. The average was 0.00010541 seconds per call.
Rolling more patches. See Issue #41169 (http://drupal.org/node/41169).
And how many calls to array2object and object2array there are on average/max page? -- Piotrek irc: #debian.pl Mors Drosophilis melanogastribus!
Piotr Krukowiecki wrote:
And how many calls to array2object and object2array there are on average/max page?
It's highly variable. Pages which list nodes tend to have some base value (1 to 3) plus 1 or 2 per node, depending on what is displayed by the theme. I have not instrumented a production site to get a running average over a day or two of usage, so I can't give you accurate numbers for average and maximum. In my simple testing, the most common number seemed to be 3 calls per page for single node pages. A page listing 10 blog teasers had 10 calls. ..chrisxj
participants (8)
-
Chris Johnson -
Dries Buytaert -
Earl Dunovant -
Keegan Quinn -
Larry Garfield -
Moshe Weitzman -
Neil Drumm -
piotr@mallorn.ii.uj.edu.pl