From 186cd1d7b0ce9aae36bd2b1f0a874226fccb9b25 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Tue, 30 Sep 2025 12:05:38 +0200 Subject: [PATCH] Use faster string construction in ext/dom in some places Many tag names are single characters, so we can use the fast string construction. In cases where a NULL name is used we can also use the empty string. This avoids some allocations and some work. --- ext/dom/attr.c | 2 +- ext/dom/documenttype.c | 6 +++++- ext/dom/dom_iterators.c | 4 ++-- ext/dom/element.c | 4 ++-- ext/dom/node.c | 11 +++++++++-- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/ext/dom/attr.c b/ext/dom/attr.c index 5a0900d657eea..3107f5a21a2be 100644 --- a/ext/dom/attr.c +++ b/ext/dom/attr.c @@ -83,7 +83,7 @@ zend_result dom_attr_name_read(dom_object *obj, zval *retval) if (php_dom_follow_spec_intern(obj)) { zend_string *str = dom_node_get_node_name_attribute_or_element((xmlNodePtr) attrp, false); - ZVAL_NEW_STR(retval, str); + ZVAL_STR(retval, str); } else { ZVAL_STRING(retval, (char *) attrp->name); } diff --git a/ext/dom/documenttype.c b/ext/dom/documenttype.c index 63da0306649a9..266c895effb27 100644 --- a/ext/dom/documenttype.c +++ b/ext/dom/documenttype.c @@ -34,7 +34,11 @@ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core- zend_result dom_documenttype_name_read(dom_object *obj, zval *retval) { DOM_PROP_NODE(xmlDtdPtr, dtdptr, obj); - ZVAL_STRING(retval, dtdptr->name ? (char *) (dtdptr->name) : ""); + if (dtdptr->name) { + ZVAL_STRING(retval, (const char *) dtdptr->name); + } else { + ZVAL_EMPTY_STRING(retval); + } return SUCCESS; } diff --git a/ext/dom/dom_iterators.c b/ext/dom/dom_iterators.c index 90e973723f6c6..9134b107925a2 100644 --- a/ext/dom/dom_iterators.c +++ b/ext/dom/dom_iterators.c @@ -127,9 +127,9 @@ static void php_dom_iterator_current_key(zend_object_iterator *iter, zval *key) if (intern->ptr != NULL) { xmlNodePtr curnode = ((php_libxml_node_ptr *)intern->ptr)->node; if (curnode->type == XML_ATTRIBUTE_NODE && php_dom_follow_spec_intern(intern)) { - ZVAL_NEW_STR(key, dom_node_get_node_name_attribute_or_element(curnode, false)); + ZVAL_STR(key, dom_node_get_node_name_attribute_or_element(curnode, false)); } else { - ZVAL_STRINGL(key, (const char *) curnode->name, xmlStrlen(curnode->name)); + ZVAL_STRINGL_FAST(key, (const char *) curnode->name, xmlStrlen(curnode->name)); } } else { ZVAL_NULL(key); diff --git a/ext/dom/element.c b/ext/dom/element.c index f9aee10802fbb..cf1a762768a87 100644 --- a/ext/dom/element.c +++ b/ext/dom/element.c @@ -122,7 +122,7 @@ zend_result dom_element_tag_name_read(dom_object *obj, zval *retval) bool uppercase = php_dom_follow_spec_intern(obj) && php_dom_ns_is_html_and_document_is_html(nodep); zend_string *result = dom_node_get_node_name_attribute_or_element((const xmlNode *) nodep, uppercase); - ZVAL_NEW_STR(retval, result); + ZVAL_STR(retval, result); return SUCCESS; } @@ -375,7 +375,7 @@ PHP_METHOD(DOMElement, getAttributeNames) } for (xmlAttrPtr attr = nodep->properties; attr; attr = attr->next) { - ZVAL_NEW_STR(&tmp, dom_node_get_node_name_attribute_or_element((const xmlNode *) attr, false)); + ZVAL_STR(&tmp, dom_node_get_node_name_attribute_or_element((const xmlNode *) attr, false)); zend_hash_next_index_insert(ht, &tmp); } } diff --git a/ext/dom/node.c b/ext/dom/node.c index 61e693fa77630..40aaf27669268 100644 --- a/ext/dom/node.c +++ b/ext/dom/node.c @@ -52,6 +52,13 @@ zend_string *dom_node_get_node_name_attribute_or_element(const xmlNode *nodep, b if (nodep->ns != NULL && nodep->ns->prefix != NULL) { ret = dom_node_concatenated_name_helper(name_len, (const char *) nodep->name, strlen((const char *) nodep->ns->prefix), (const char *) nodep->ns->prefix); } else { + if (name_len == 1) { + if (uppercase) { + return ZSTR_CHAR(zend_toupper_ascii(*nodep->name)); + } else { + return ZSTR_CHAR((zend_uchar) *nodep->name); + } + } ret = zend_string_init((const char *) nodep->name, name_len, false); } if (uppercase) { @@ -89,7 +96,7 @@ zend_result dom_node_node_name_read(dom_object *obj, zval *retval) uppercase = php_dom_follow_spec_intern(obj) && php_dom_ns_is_html_and_document_is_html(nodep); ZEND_FALLTHROUGH; case XML_ATTRIBUTE_NODE: - ZVAL_NEW_STR(retval, dom_node_get_node_name_attribute_or_element(nodep, uppercase)); + ZVAL_STR(retval, dom_node_get_node_name_attribute_or_element(nodep, uppercase)); break; case XML_NAMESPACE_DECL: { xmlNsPtr ns = nodep->ns; @@ -635,7 +642,7 @@ zend_result dom_node_local_name_read(dom_object *obj, zval *retval) DOM_PROP_NODE(xmlNodePtr, nodep, obj); if (nodep->type == XML_ELEMENT_NODE || nodep->type == XML_ATTRIBUTE_NODE || nodep->type == XML_NAMESPACE_DECL) { - ZVAL_STRING(retval, (char *) (nodep->name)); + ZVAL_STRING_FAST(retval, (const char *) (nodep->name)); } else { ZVAL_NULL(retval); }