mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Implement cache slot optimization for XMLReader (#17232)
This commit is contained in:
parent
26244c7dcd
commit
d480c04be1
3 changed files with 80 additions and 4 deletions
|
@ -236,5 +236,8 @@ PHP 8.5 UPGRADE NOTES
|
||||||
14. Performance Improvements
|
14. Performance Improvements
|
||||||
========================================
|
========================================
|
||||||
|
|
||||||
|
- XMLReader:
|
||||||
|
. Improved property access performance.
|
||||||
|
|
||||||
- XMLWriter:
|
- XMLWriter:
|
||||||
. Improved performance and reduce memory consumption.
|
. Improved performance and reduce memory consumption.
|
||||||
|
|
|
@ -123,10 +123,25 @@ static zval *xmlreader_get_property_ptr_ptr(zend_object *object, zend_string *na
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
static xmlreader_prop_handler *xmlreader_get_prop_handler(zend_string *name, void **cache_slot)
|
||||||
|
{
|
||||||
|
/* We don't store the `ce` as that may match with how the std cache slot code works in the fallback,
|
||||||
|
* instead use the prop handlers table as `ce`. */
|
||||||
|
if (cache_slot && cache_slot[0] == &xmlreader_prop_handlers) {
|
||||||
|
return cache_slot[1];
|
||||||
|
} else {
|
||||||
|
xmlreader_prop_handler *hnd = zend_hash_find_ptr(&xmlreader_prop_handlers, name);
|
||||||
|
if (hnd != NULL && cache_slot) {
|
||||||
|
CACHE_POLYMORPHIC_PTR_EX(cache_slot, &xmlreader_prop_handlers, hnd);
|
||||||
|
}
|
||||||
|
return hnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int xmlreader_has_property(zend_object *object, zend_string *name, int type, void **cache_slot)
|
static int xmlreader_has_property(zend_object *object, zend_string *name, int type, void **cache_slot)
|
||||||
{
|
{
|
||||||
xmlreader_object *obj = php_xmlreader_fetch_object(object);
|
xmlreader_object *obj = php_xmlreader_fetch_object(object);
|
||||||
xmlreader_prop_handler *hnd = zend_hash_find_ptr(&xmlreader_prop_handlers, name);
|
xmlreader_prop_handler *hnd = xmlreader_get_prop_handler(name, cache_slot);
|
||||||
|
|
||||||
if (hnd != NULL) {
|
if (hnd != NULL) {
|
||||||
if (type == ZEND_PROPERTY_EXISTS) {
|
if (type == ZEND_PROPERTY_EXISTS) {
|
||||||
|
@ -162,7 +177,7 @@ static zval *xmlreader_read_property(zend_object *object, zend_string *name, int
|
||||||
{
|
{
|
||||||
zval *retval = NULL;
|
zval *retval = NULL;
|
||||||
xmlreader_object *obj = php_xmlreader_fetch_object(object);
|
xmlreader_object *obj = php_xmlreader_fetch_object(object);
|
||||||
xmlreader_prop_handler *hnd = zend_hash_find_ptr(&xmlreader_prop_handlers, name);
|
xmlreader_prop_handler *hnd = xmlreader_get_prop_handler(name, cache_slot);
|
||||||
|
|
||||||
if (hnd != NULL) {
|
if (hnd != NULL) {
|
||||||
if (xmlreader_property_reader(obj, hnd, rv) == FAILURE) {
|
if (xmlreader_property_reader(obj, hnd, rv) == FAILURE) {
|
||||||
|
@ -181,7 +196,7 @@ static zval *xmlreader_read_property(zend_object *object, zend_string *name, int
|
||||||
/* {{{ xmlreader_write_property */
|
/* {{{ xmlreader_write_property */
|
||||||
static zval *xmlreader_write_property(zend_object *object, zend_string *name, zval *value, void **cache_slot)
|
static zval *xmlreader_write_property(zend_object *object, zend_string *name, zval *value, void **cache_slot)
|
||||||
{
|
{
|
||||||
xmlreader_prop_handler *hnd = zend_hash_find_ptr(&xmlreader_prop_handlers, name);
|
xmlreader_prop_handler *hnd = xmlreader_get_prop_handler(name, cache_slot);
|
||||||
|
|
||||||
if (hnd != NULL) {
|
if (hnd != NULL) {
|
||||||
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));
|
||||||
|
@ -195,7 +210,7 @@ static zval *xmlreader_write_property(zend_object *object, zend_string *name, zv
|
||||||
|
|
||||||
void xmlreader_unset_property(zend_object *object, zend_string *name, void **cache_slot)
|
void xmlreader_unset_property(zend_object *object, zend_string *name, void **cache_slot)
|
||||||
{
|
{
|
||||||
xmlreader_prop_handler *hnd = zend_hash_find_ptr(&xmlreader_prop_handlers, name);
|
xmlreader_prop_handler *hnd = xmlreader_get_prop_handler(name, cache_slot);
|
||||||
|
|
||||||
if (hnd != NULL) {
|
if (hnd != NULL) {
|
||||||
zend_throw_error(NULL, "Cannot unset %s::$%s", ZSTR_VAL(object->ce->name), ZSTR_VAL(name));
|
zend_throw_error(NULL, "Cannot unset %s::$%s", ZSTR_VAL(object->ce->name), ZSTR_VAL(name));
|
||||||
|
|
58
ext/xmlreader/tests/cache_slot.phpt
Normal file
58
ext/xmlreader/tests/cache_slot.phpt
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
--TEST--
|
||||||
|
Cache slot test
|
||||||
|
--EXTENSIONS--
|
||||||
|
xmlreader
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Test1 {
|
||||||
|
function __construct(public string $localName) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[AllowDynamicProperties]
|
||||||
|
class Test2 extends XMLReader {
|
||||||
|
}
|
||||||
|
|
||||||
|
function readLocalName($obj) {
|
||||||
|
for ($i = 0; $i < 2; $i++)
|
||||||
|
var_dump($obj->localName);
|
||||||
|
}
|
||||||
|
|
||||||
|
function readTestProp($obj) {
|
||||||
|
for ($i = 0; $i < 2; $i++)
|
||||||
|
var_dump($obj->testProp);
|
||||||
|
}
|
||||||
|
|
||||||
|
$reader = XMLReader::fromString("<root/>");
|
||||||
|
$reader->read();
|
||||||
|
$test1 = new Test1("hello");
|
||||||
|
|
||||||
|
readLocalName($reader);
|
||||||
|
readLocalName($test1);
|
||||||
|
readLocalName($reader);
|
||||||
|
|
||||||
|
$test2 = new Test2;
|
||||||
|
$test2->testProp = 1;
|
||||||
|
|
||||||
|
readTestProp($test2);
|
||||||
|
readTestProp($reader);
|
||||||
|
readTestProp($test2);
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
string(4) "root"
|
||||||
|
string(4) "root"
|
||||||
|
string(5) "hello"
|
||||||
|
string(5) "hello"
|
||||||
|
string(4) "root"
|
||||||
|
string(4) "root"
|
||||||
|
int(1)
|
||||||
|
int(1)
|
||||||
|
|
||||||
|
Warning: Undefined property: XMLReader::$testProp in %s on line %d
|
||||||
|
NULL
|
||||||
|
|
||||||
|
Warning: Undefined property: XMLReader::$testProp in %s on line %d
|
||||||
|
NULL
|
||||||
|
int(1)
|
||||||
|
int(1)
|
Loading…
Add table
Add a link
Reference in a new issue