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;
|
||||
}
|
||||
|
||||
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 */
|
||||
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);
|
||||
zval *retval;
|
||||
dom_prop_handler *hnd = NULL;
|
||||
|
||||
if (obj->prop_handler != NULL) {
|
||||
hnd = zend_hash_find_ptr(obj->prop_handler, name);
|
||||
}
|
||||
const dom_prop_handler *hnd = dom_get_prop_handler(obj, name, cache_slot);
|
||||
|
||||
if (hnd) {
|
||||
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)
|
||||
{
|
||||
dom_object *obj = php_dom_obj_from_obj(object);
|
||||
dom_prop_handler *hnd = NULL;
|
||||
|
||||
if (obj->prop_handler != NULL) {
|
||||
hnd = zend_hash_find_ptr(obj->prop_handler, name);
|
||||
}
|
||||
const dom_prop_handler *hnd = dom_get_prop_handler(obj, name, cache_slot);
|
||||
|
||||
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));
|
||||
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));
|
||||
zval tmp;
|
||||
ZVAL_COPY(&tmp, value);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue