Bug #79700 [NEW]: wrong use of libxml oldNs leads to performance problem

From: Date: Mon, 15 Jun 2020 01:06:10 +0000
Subject: Bug #79700 [NEW]: wrong use of libxml oldNs leads to performance problem
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-227483@lists.php.net to get a copy of this message
From: beberlei Operating system: PHP version: 7.4.7 Package: DOM XML related Bug Type: Bug Bug description:wrong use of libxml oldNs leads to performance problem Description: ------------ In libxml, the xmlDoc->oldNs pointer is used by xmlSearchNs* functions for holding the xmlns:xml namespace "http://www.w3.org/XML/1998/namespace". https://github.com/GNOME/libxml2/blob/mainline/include/libxml/tree.h#L140 https://github.com/GNOME/libxml2/blob/mainline/tree.c#L5992 The specification says this xml namespace MAY but need not be declared on a document, but still exists implicitly. This is what the xmlDoc->oldNs property is for, holding this namespace outside the nodes. Usually a namespace is attached to a node. PHP Dom however uses xmlDoc->oldNs to store any namespaces of new namespaced elements or attributes during reconciliation. In combination with a list append that does not check for duplicates this causes exponential performance degradation in the number of nodes. Test script: --------------- <?php $dom = new DOMDocument(); $root = $dom->createElementNS('http://www.w3.org/2000/xhtml', 'html'); $dom->appendChild($root); $s = microtime(true); for ($i = 0; $i < 10000; $i++) { $element = $dom->createElementNS('http://www.w3.org/2000/xhtml', 'p', 'Hello World'); $root->appendChild($element); } echo number_format(microtime(true) - $s, 6) . "\n"; $s = microtime(true); for ($i = 0; $i < 10000; $i++) { $element = $dom->createElementNS('http://www.w3.org/2000/xhtml', 'p', 'Hello World'); $root->appendChild($element); } echo number_format(microtime(true) - $s, 6) . "\n"; $s = microtime(true); for ($i = 0; $i < 10000; $i++) { $element = $dom->createElementNS('http://www.w3.org/2000/xhtml', 'p', 'Hello World'); $root->appendChild($element); } echo number_format(microtime(true) - $s, 6) . "\n"; Expected result: ---------------- Roughly the same time for each block of 10000 nodes. Actual result: -------------- Time increases massively for each consecutive block from 200 ms to 1200ms to 2400ms (on my machine). -- Edit bug report at https://bugs.php.net/bug.php?id=79700&edit=1 -- Fix committed: https://bugs.php.net/fix.php?id=79700&r=fixed Fixed in release: https://bugs.php.net/fix.php?id=79700&r=alreadyfixed Need backtrace: https://bugs.php.net/fix.php?id=79700&r=needtrace Need Reproduce Script: https://bugs.php.net/fix.php?id=79700&r=needscript Try newer version: https://bugs.php.net/fix.php?id=79700&r=oldversion Not developer issue: https://bugs.php.net/fix.php?id=79700&r=support Expected behavior: https://bugs.php.net/fix.php?id=79700&r=notwrong Not enough info: https://bugs.php.net/fix.php?id=79700&r=notenoughinfo Submitted twice: https://bugs.php.net/fix.php?id=79700&r=submittedtwice register_globals: https://bugs.php.net/fix.php?id=79700&r=globals PHP version support discontinued: https://bugs.php.net/fix.php?id=79700&r=phptooold Daylight Savings: https://bugs.php.net/fix.php?id=79700&r=dst IIS Stability: https://bugs.php.net/fix.php?id=79700&r=isapi Install GNU Sed: https://bugs.php.net/fix.php?id=79700&r=gnused Floating point limitations: https://bugs.php.net/fix.php?id=79700&r=float No Zend Extensions: https://bugs.php.net/fix.php?id=79700&r=nozend MySQL Configuration Error: https://bugs.php.net/fix.php?id=79700&r=mysqlcfg

« previous php.bugs (#227483) next »