mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Optimize DOM property access (#15626)
For the read and write implementation, store the handler pointer in the first cache slot. For the write implementation, use the second cache slot to store the property info. For a micro-benchmark that performs a write: ```php $dom = new DOMDocument; for ($i=0;$i<9999999;$i++) $dom->strictErrorChecking = false; ``` I obtain the following results on an i7-4790: ``` ./sapi/cli/php ./write.php ran 1.42 ± 0.08 times faster than ./sapi/cli/php_old ./write.php ``` For a micro-benchmark that performs a read: ```php $dom = new DOMDocument; for ($i=0;$i<9999999;$i++) $dom->strictErrorChecking; ``` I obtain the following results on the same machine: ``` ./sapi/cli/php ./read.php ran 1.29 ± 0.13 times faster than ./sapi/cli/php_old ./read.php ```
This commit is contained in:
parent
0268cb0343
commit
367f303efa
1 changed files with 33 additions and 12 deletions
|
@ -365,16 +365,31 @@ static zval *dom_get_property_ptr_ptr(zend_object *object, zend_string *name, in
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static zend_always_inline const dom_prop_handler *dom_get_prop_handler(const dom_object *obj, zend_string *name, void **cache_slot)
|
||||||
|
{
|
||||||
|
const dom_prop_handler *hnd = NULL;
|
||||||
|
|
||||||
|
if (obj->prop_handler != NULL) {
|
||||||
|
if (cache_slot) {
|
||||||
|
hnd = *cache_slot;
|
||||||
|
}
|
||||||
|
if (!hnd) {
|
||||||
|
hnd = zend_hash_find_ptr(obj->prop_handler, name);
|
||||||
|
if (cache_slot) {
|
||||||
|
*cache_slot = (void *) hnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hnd;
|
||||||
|
}
|
||||||
|
|
||||||
/* {{{ dom_read_property */
|
/* {{{ dom_read_property */
|
||||||
zval *dom_read_property(zend_object *object, zend_string *name, int type, void **cache_slot, zval *rv)
|
zval *dom_read_property(zend_object *object, zend_string *name, int type, void **cache_slot, zval *rv)
|
||||||
{
|
{
|
||||||
dom_object *obj = php_dom_obj_from_obj(object);
|
dom_object *obj = php_dom_obj_from_obj(object);
|
||||||
zval *retval;
|
zval *retval;
|
||||||
dom_prop_handler *hnd = NULL;
|
const dom_prop_handler *hnd = dom_get_prop_handler(obj, name, cache_slot);
|
||||||
|
|
||||||
if (obj->prop_handler != NULL) {
|
|
||||||
hnd = zend_hash_find_ptr(obj->prop_handler, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hnd) {
|
if (hnd) {
|
||||||
int ret = hnd->read_func(obj, rv);
|
int ret = hnd->read_func(obj, rv);
|
||||||
|
@ -394,19 +409,25 @@ zval *dom_read_property(zend_object *object, zend_string *name, int type, void *
|
||||||
zval *dom_write_property(zend_object *object, zend_string *name, zval *value, void **cache_slot)
|
zval *dom_write_property(zend_object *object, zend_string *name, zval *value, void **cache_slot)
|
||||||
{
|
{
|
||||||
dom_object *obj = php_dom_obj_from_obj(object);
|
dom_object *obj = php_dom_obj_from_obj(object);
|
||||||
dom_prop_handler *hnd = NULL;
|
const dom_prop_handler *hnd = dom_get_prop_handler(obj, name, cache_slot);
|
||||||
|
|
||||||
if (obj->prop_handler != NULL) {
|
|
||||||
hnd = zend_hash_find_ptr(obj->prop_handler, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hnd) {
|
if (hnd) {
|
||||||
if (!hnd->write_func) {
|
if (UNEXPECTED(!hnd->write_func)) {
|
||||||
zend_readonly_property_modification_error_ex(ZSTR_VAL(object->ce->name), ZSTR_VAL(name));
|
zend_readonly_property_modification_error_ex(ZSTR_VAL(object->ce->name), ZSTR_VAL(name));
|
||||||
return &EG(error_zval);
|
return &EG(error_zval);
|
||||||
}
|
}
|
||||||
|
|
||||||
zend_property_info *prop = zend_get_property_info(object->ce, name, /* silent */ true);
|
zend_property_info *prop = NULL;
|
||||||
|
if (cache_slot) {
|
||||||
|
prop = *(cache_slot + 1);
|
||||||
|
}
|
||||||
|
if (!prop) {
|
||||||
|
prop = zend_get_property_info(object->ce, name, /* silent */ true);
|
||||||
|
if (cache_slot) {
|
||||||
|
*(cache_slot + 1) = prop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ZEND_ASSERT(prop && ZEND_TYPE_IS_SET(prop->type));
|
ZEND_ASSERT(prop && ZEND_TYPE_IS_SET(prop->type));
|
||||||
zval tmp;
|
zval tmp;
|
||||||
ZVAL_COPY(&tmp, value);
|
ZVAL_COPY(&tmp, value);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue