Property access slowness

php.internals

Sterling Hughes

23 years ago
Hi, Property access with PHP5 is very slow compared to PHP4. The reason for this is that property access must be verified *every* time. This seems really unnecessary unless we're indirectly accessing properties. Can/Should this be moved to zend_compile.c for everything that doesn't rely on indirect reference? -Sterling
-- "Programming today is a race between software engineers stirring to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning." - Unknown

Andi Gutmans

23 years ago
At 12:15 PM 5/24/2003 -0400, Sterling Hughes wrote:
>Hi, > >Property access with PHP5 is very slow compared to PHP4. The reason for >this is that property access must be verified *every* time. This seems >really unnecessary unless we're indirectly accessing properties. > >Can/Should this be moved to zend_compile.c for everything that doesn't >rely on indirect reference?
Which accesses are slower, $obj->prop, $this->prop or both? Andi

Sterling Hughes

23 years ago
On Sun, 2003-05-25 at 00:08, Andi Gutmans wrote:
> At 12:15 PM 5/24/2003 -0400, Sterling Hughes wrote: > >Hi, > > > >Property access with PHP5 is very slow compared to PHP4. The reason for > >this is that property access must be verified *every* time. This seems > >really unnecessary unless we're indirectly accessing properties. > > > >Can/Should this be moved to zend_compile.c for everything that doesn't > >rely on indirect reference? > > Which accesses are slower, $obj->prop, $this->prop or both?
I just benchmarked $obj->prop, but I would imagine both. Its handlers->property_read(), that's the bottleneck. -Sterling
> > Andi
-- "The computer programmer is a creator of universes for which he alone is responsible. Universes of virtually unlimited complexity can be created in the form of computer programs." - Joseph Weizenbaum

Andi Gutmans

23 years ago
At 08:59 AM 5/25/2003 -0400, Sterling Hughes wrote:
>On Sun, 2003-05-25 at 00:08, Andi Gutmans wrote: > > At 12:15 PM 5/24/2003 -0400, Sterling Hughes wrote: > > >Hi, > > > > > >Property access with PHP5 is very slow compared to PHP4. The reason for > > >this is that property access must be verified *every* time. This seems > > >really unnecessary unless we're indirectly accessing properties. > > > > > >Can/Should this be moved to zend_compile.c for everything that doesn't > > >rely on indirect reference? > > > > Which accesses are slower, $obj->prop, $this->prop or both? > >I just benchmarked $obj->prop, but I would imagine both. Its >handlers->property_read(), that's the bottleneck.
It was a given that PPP would slightly slow things down but it's worth it. If we find a clean way of speeding it up I'd welcome it but I wouldn't want to take extreme measures like not using zval's for properties or other ugly solutions just to speed things up a bit. I would like to hear how $this->prop compares to PHP 4 (on more than one architecture) because the $this lookup is supposed to be saved in PHP 5. So we might (hopefully) be faster in PHP 5. Andi

Zeev Suraski

23 years ago
At 19:15 24.05.2003, Sterling Hughes wrote:
>Hi, > >Property access with PHP5 is very slow compared to PHP4. The reason for >this is that property access must be verified *every* time. This seems >really unnecessary unless we're indirectly accessing properties.
It has to be verified each time, because we're typeless, and can't do stuff like that in compile time. It's not related to indirect reference... Zeev

Alan Knowles

23 years ago
Sorry for commenting & not looking at the code, but do you flag a class as having any ppp in it, and do that check first.. - so at least non-ppp code will be slightly faster...? Zeev Suraski wrote:
> At 19:15 24.05.2003, Sterling Hughes wrote: > >> Hi, >> >> Property access with PHP5 is very slow compared to PHP4. The reason for >> this is that property access must be verified *every* time. This seems >> really unnecessary unless we're indirectly accessing properties. > > > It has to be verified each time, because we're typeless, and can't do > stuff like that in compile time. It's not related to indirect reference... > > Zeev > >
-- Can you help out? Need Consulting Services or Know of a Job? http://www.akbkhome.com

Zeev Suraski

23 years ago
At 14:05 25/05/2003, Alan Knowles wrote:
>Sorry for commenting & not looking at the code, but do you flag a class as >having any ppp in it, and do that check first.. - so at least non-ppp code >will be slightly faster...?
Currently no... Zeev

Sterling Hughes

23 years ago
On Sun, 2003-05-25 at 04:24, Zeev Suraski wrote:
> At 19:15 24.05.2003, Sterling Hughes wrote: > >Hi, > > > >Property access with PHP5 is very slow compared to PHP4. The reason for > >this is that property access must be verified *every* time. This seems > >really unnecessary unless we're indirectly accessing properties. > > It has to be verified each time, because we're typeless, and can't do stuff > like that in compile time. It's not related to indirect reference... >
Ahh, yeah. Can we at least embed property information within the ce->properties hashtable? Currently accessing properties in PHP5 is *15%* slower. Denormalizing the properties_info, should give a nice performance gain. -Sterling
> Zeev
-- "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do, it blows away your whole leg." - Bjarne Stroustrup

Zeev Suraski

23 years ago
At 15:58 25/05/2003, Sterling Hughes wrote:
>On Sun, 2003-05-25 at 04:24, Zeev Suraski wrote: > > At 19:15 24.05.2003, Sterling Hughes wrote: > > >Hi, > > > > > >Property access with PHP5 is very slow compared to PHP4. The reason for > > >this is that property access must be verified *every* time. This seems > > >really unnecessary unless we're indirectly accessing properties. > > > > It has to be verified each time, because we're typeless, and can't do > stuff > > like that in compile time. It's not related to indirect reference... > > > >Ahh, yeah. Can we at least embed property information within the >ce->properties hashtable? Currently accessing properties in PHP5 is >*15%* slower. Denormalizing the properties_info, should give a nice >performance gain.
There's no ce->properties, it sits in each object instance, so not really... We could possibly look into some optimization along the lines of what Alan suggested. I haven't given it much thought, but apparently, if a class and its entire ancestors tree doesn't use PPP - it may be possible to save the get_property_info call. Remember that in general, the fact that property access is slower is no news - we know it would be. The gain in reduced copying should buy us some performance, though. Zeev

Sterling Hughes

23 years ago
On Sun, 2003-05-25 at 10:57, Zeev Suraski wrote:
> At 15:58 25/05/2003, Sterling Hughes wrote: > >On Sun, 2003-05-25 at 04:24, Zeev Suraski wrote: > > > At 19:15 24.05.2003, Sterling Hughes wrote: > > > >Hi, > > > > > > > >Property access with PHP5 is very slow compared to PHP4. The reason for > > > >this is that property access must be verified *every* time. This seems > > > >really unnecessary unless we're indirectly accessing properties. > > > > > > It has to be verified each time, because we're typeless, and can't do > > stuff > > > like that in compile time. It's not related to indirect reference... > > > > > > >Ahh, yeah. Can we at least embed property information within the > >ce->properties hashtable? Currently accessing properties in PHP5 is > >*15%* slower. Denormalizing the properties_info, should give a nice > >performance gain. > > There's no ce->properties, it sits in each object instance, so not > really... We could possibly look into some optimization along the lines of > what Alan suggested. I haven't given it much thought, but apparently, if a > class and its entire ancestors tree doesn't use PPP - it may be possible to > save the get_property_info call. > Remember that in general, the fact that property access is slower is no > news - we know it would be. The gain in reduced copying should buy us some > performance, though. >
I'm must be going senile then :) Let zobj be an object zval. zobj->properties and zobj->ce->properties_info is what I'm talking about. When object properties are looked up, via read_property(), first a hashtable access is done on zobj->ce->property_info, to find the property access levels, then the property access levels are verified. Then the lookup is done on zobj->properties to find the property value, and we are all happy. A first time lookup is fine, but per-object this need not be looked up and verified more than once. Therefore, if we change each individual property to contain an extra field, verified, we can save this check each time the object property is accessed. Something like: struct obj_property { zval *value; int verified; }; Where the verified state is maintained per-object, we should be able to cut repeated accesses down to nothing. Unless I'm missing something? -Sterling
> Zeev
-- "That stuff's easy compared to installing Horde" - Alan Knowles, In response to my applause for creating a LALR parser for PHP.

Zeev Suraski

23 years ago
At 17:06 25/05/2003, Sterling Hughes wrote:
>I'm must be going senile then :) Let zobj be an object zval. >zobj->properties and zobj->ce->properties_info is what I'm talking >about. > >When object properties are looked up, via read_property(), first a >hashtable access is done on zobj->ce->property_info, to find the >property access levels, then the property access levels are verified. >Then the lookup is done on zobj->properties to find the property value, >and we are all happy. > >A first time lookup is fine, but per-object this need not be looked up >and verified more than once. Therefore, if we change each individual >property to contain an extra field, verified, we can save this check >each time the object property is accessed. Something like: > >struct obj_property { > zval *value; > int verified; >}; > >Where the verified state is maintained per-object, we should be able to >cut repeated accesses down to nothing. Unless I'm missing something?
I think you're missing a bit :) What does 'verified' mean exactly, that someone can access this property? Or do you want to keep a list of contexts that are allowed to access it, vs. ones that are not? What you might be thinking is to copy the property information from the class entry into each individual property. That might work and save us a lookup, but it would also be a horrible memory (and probably also performance) hog to maintain. The problem is that if you go down to basics, the property information belongs in the class entry, whereas the value of each individual property belongs in the object instances, and thus it cannot be in the same place. One optimization that we could make is keep a pointer from each property value to its corresponding property_info entry. The price of that is some additional memory overhead, plus the fact that we'd have to give up the standard zval sybmol table that objects today have, that can bring about quite a few annoying side effects. It won't completely annihilate the overhead either - because we'll still have to make the checks, we'd just be saving the lookup. I'll try to think of some creative ways to speed things up, but profiling it a bit and knowing where we spend the bulk of the time would help. Zeev

Sterling Hughes

23 years ago
On Sun, 2003-05-25 at 11:49, Zeev Suraski wrote:
> At 17:06 25/05/2003, Sterling Hughes wrote: > >I'm must be going senile then :) Let zobj be an object zval. > >zobj->properties and zobj->ce->properties_info is what I'm talking > >about. > > > >When object properties are looked up, via read_property(), first a > >hashtable access is done on zobj->ce->property_info, to find the > >property access levels, then the property access levels are verified. > >Then the lookup is done on zobj->properties to find the property value, > >and we are all happy. > > > >A first time lookup is fine, but per-object this need not be looked up > >and verified more than once. Therefore, if we change each individual > >property to contain an extra field, verified, we can save this check > >each time the object property is accessed. Something like: > > > >struct obj_property { > > zval *value; > > int verified; > >}; > > > >Where the verified state is maintained per-object, we should be able to > >cut repeated accesses down to nothing. Unless I'm missing something? > > I think you're missing a bit :) What does 'verified' mean exactly, that > someone can access this property? Or do you want to keep a list of > contexts that are allowed to access it, vs. ones that are not?
> > What you might be thinking is to copy the property information from the > class entry into each individual property. That might work and save us a > lookup, but it would also be a horrible memory (and probably also > performance) hog to maintain. The problem is that if you go down to > basics, the property information belongs in the class entry, whereas the > value of each individual property belongs in the object instances, and thus > it cannot be in the same place. > > One optimization that we could make is keep a pointer from each property > value to its corresponding property_info entry. The price of that is some > additional memory overhead, plus the fact that we'd have to give up the > standard zval sybmol table that objects today have, that can bring about > quite a few annoying side effects. It won't completely annihilate the > overhead either - because we'll still have to make the checks, we'd just be > saving the lookup. >
Yeah, this was my initial thought, but instead of maintaining a pointer to property_info, we can just maintain the integer access value. I really don't care which is done, as they are both 4 bytes.
> I'll try to think of some creative ways to speed things up, but profiling > it a bit and knowing where we spend the bulk of the time would help. >
Use cachegrind. Profiling is what lead me to this idea. :) -Sterling
> Zeev
-- Good judgement comes from experience, and experience comes from bad judgement. - Fred Brooks

Sterling Hughes

23 years ago
> > > One optimization that we could make is keep a pointer from each property > > value to its corresponding property_info entry. The price of that is some > > additional memory overhead, plus the fact that we'd have to give up the > > standard zval sybmol table that objects today have, that can bring about > > quite a few annoying side effects. It won't completely annihilate the > > overhead either - because we'll still have to make the checks, we'd just be > > saving the lookup. > >
Just a note that you actually save more than a lookup. You save a lookup "best case." -Sterling
-- "Whether you think you can or think you can't -- you are right." - Henry Ford