From 03fd6334f23756d50ad901878409068a9b76b37a Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 18 Jul 2024 00:04:31 +0200 Subject: [PATCH] Optimize ext/dom $wholeText MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use our own string builder instead of using libxml's and then having to copy over. For the following test: ``` $dom = Dom\HTMLDocument::createEmpty(); $root = $dom->appendChild($dom->createElement('root')); $root->append('abc', 'def', 'ghi'); $f = $root->firstChild; for ($i = 0; $i < 1000000; $i++) $f->wholeText; ``` The following results were obtained on an i7-4790: ``` Benchmark 1: ./sapi/cli/php x.php Time (mean ± σ): 57.2 ms ± 2.3 ms [User: 53.2 ms, System: 3.4 ms] Range (min … max): 54.7 ms … 69.3 ms 52 runs Benchmark 2: ./sapi/cli/php_old x.php Time (mean ± σ): 89.4 ms ± 3.4 ms [User: 85.6 ms, System: 3.0 ms] Range (min … max): 86.1 ms … 105.8 ms 32 runs Summary ./sapi/cli/php x.php ran 1.56 ± 0.09 times faster than ./sapi/cli/php_old x.php ``` --- ext/dom/text.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/ext/dom/text.c b/ext/dom/text.c index ef0d5d0cef6f7..2add9dcc8c4c7 100644 --- a/ext/dom/text.c +++ b/ext/dom/text.c @@ -68,7 +68,7 @@ zend_result dom_text_whole_text_read(dom_object *obj, zval *retval) { DOM_PROP_NODE(xmlNodePtr, node, obj); - xmlChar *wholetext = NULL; + smart_str str = {0}; /* Find starting text node */ while (node->prev && ((node->prev->type == XML_TEXT_NODE) || (node->prev->type == XML_CDATA_SECTION_NODE))) { @@ -77,16 +77,11 @@ zend_result dom_text_whole_text_read(dom_object *obj, zval *retval) /* concatenate all adjacent text and cdata nodes */ while (node && ((node->type == XML_TEXT_NODE) || (node->type == XML_CDATA_SECTION_NODE))) { - wholetext = xmlStrcat(wholetext, node->content); + smart_str_appends(&str, (const char *) node->content); node = node->next; } - if (wholetext != NULL) { - ZVAL_STRING(retval, (char *) wholetext); - xmlFree(wholetext); - } else { - ZVAL_EMPTY_STRING(retval); - } + ZVAL_STR(retval, smart_str_extract(&str)); return SUCCESS; }