mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
dom: Optimize splitText() (#20371)
This avoids duplicating the intermediate strings, by transferring
ownership.
It's hard to measure the improvement in a reliable way, as we have to
operate on the same node. The following benchmark shows a nice
improvement (although not perfect as a benchmark):
```php
<?php
$dom = new DOMDocument;
$dom->loadXML('<root>testabcdef</root>');
$text = $dom->documentElement->firstChild;
for ($i = 0; $i < 1000000; $i++) {
$text2 = clone $text;
$text2->splitText(5);
}
```
Only tested on my desktop i7-4790:
```
Benchmark 1: ./sapi/cli/php x.php
Time (mean ± σ): 284.1 ms ± 2.8 ms [User: 280.0 ms, System: 3.0 ms]
Range (min … max): 281.4 ms … 291.3 ms 10 runs
Benchmark 2: ./sapi/cli/php_old x.php
Time (mean ± σ): 314.0 ms ± 7.8 ms [User: 309.2 ms, System: 2.9 ms]
Range (min … max): 306.5 ms … 328.0 ms 10 runs
Summary
./sapi/cli/php x.php ran
1.11 ± 0.03 times faster than ./sapi/cli/php_old x.php
```
This commit is contained in:
@@ -117,5 +117,8 @@ PHP 8.6 UPGRADE NOTES
|
||||
. Arguments are now passed more efficiently to known constructors (e.g. when
|
||||
using new self()).
|
||||
|
||||
- DOM:
|
||||
. Made splitText() faster and consume less memory.
|
||||
|
||||
- JSON:
|
||||
. Improve performance of encoding arrays and objects.
|
||||
|
||||
@@ -127,17 +127,18 @@ PHP_METHOD(DOMText, splitText)
|
||||
first = xmlUTF8Strndup(cur, (int)offset);
|
||||
second = xmlUTF8Strsub(cur, (int)offset, (int)(length - offset));
|
||||
|
||||
xmlNodeSetContent(node, first);
|
||||
nnode = xmlNewDocText(node->doc, second);
|
||||
|
||||
xmlFree(first);
|
||||
xmlFree(second);
|
||||
xmlNodeSetContent(node, NULL);
|
||||
node->content = first;
|
||||
nnode = xmlNewDocText(node->doc, NULL);
|
||||
|
||||
if (nnode == NULL) {
|
||||
xmlFree(second);
|
||||
php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true);
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
nnode->content = second;
|
||||
|
||||
if (node->parent != NULL) {
|
||||
nnode->type = XML_ELEMENT_NODE;
|
||||
xmlAddNextSibling(node, nnode);
|
||||
|
||||
Reference in New Issue
Block a user