Last active
April 15, 2019 09:29
-
-
Save Luxian/1c732d13c12ca03835828a1553c39e4f to your computer and use it in GitHub Desktop.
DOMNode::C14N() is way slower on created DOMDocuments than loaded ones
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* This code demonstrates the performance difference when calling | |
* DOMNode::C14N() on a generated DOMDocument versus on a DOMDocument that was | |
* loaded from a string. | |
* | |
* Calling DOMDocument::normalizeDocument() doesn't make any difference. | |
* | |
* Output example: | |
* Testing with 500 items | |
* Native DOM (not normalized)… 2.55357 seconds | |
* Native DOM (normalized)… 2.52199 seconds | |
* Export and re-import DOM… 0.06444 seconds | |
*/ | |
define('NUMBER_OF_ITEMS', 500); | |
define('XML_NAME_SPACE', 'http://example.com/xml'); | |
echo sprintf('Testing with %d items', NUMBER_OF_ITEMS) . PHP_EOL; | |
echo 'Generated DOM… '; | |
$nativeDOM = generate_random_dom(); | |
$s = microtime(true); | |
iterate_with_xpath($nativeDOM); | |
echo number_format(microtime(true) - $s, 5) . ' seconds' . PHP_EOL; | |
echo 'Generated DOM with normalizeDocument()… '; | |
$nativeDOMNormalized = generate_random_dom(); | |
$s = microtime(true); | |
$nativeDOMNormalized->normalizeDocument(); | |
iterate_with_xpath($nativeDOMNormalized); | |
echo number_format(microtime(true) - $s, 5) . ' seconds' . PHP_EOL; | |
echo 'Export and re-import DOM… '; | |
$dom3 = generate_random_dom(); | |
$s = microtime(true); | |
$importedXmlString = new \DOMDocument('1.0', 'UTF-8'); | |
$importedXmlString->loadXML($dom3->saveXML()); | |
iterate_with_xpath($importedXmlString); | |
echo number_format(microtime(true) - $s, 5) . ' seconds' . PHP_EOL; | |
/** | |
* Iterate over items' content and call C14N | |
* | |
* @param \DOMDocument $dom | |
*/ | |
function iterate_with_xpath(\DOMDocument $dom): void | |
{ | |
$xpath = new \DOMXPath($dom); | |
$xpath->registerNamespace('listElement', XML_NAME_SPACE); | |
/** @var \DOMElement $item */ | |
foreach($xpath->query('//listElement:alpha', null, XML_NAME_SPACE) as $item) { | |
$item->C14N(); | |
} | |
} | |
/** | |
* Generate random DOMDocument | |
* | |
* Example: | |
* <listElement> | |
* <listItem index="0"> | |
* <alpha>random value here</alpha> | |
* </listItem> | |
* ... | |
* </listElement> | |
* | |
* @return \DOMDocument | |
*/ | |
function generate_random_dom(): \DOMDocument | |
{ | |
$dom = new \DOMDocument(); | |
$dom->formatOutput = true; | |
/** @var \DOMElement $list */ | |
$list = $dom->createElementNS(XML_NAME_SPACE, 'listElement'); | |
$dom->appendChild($list); | |
for($i = 0; $i < NUMBER_OF_ITEMS; $i++) { | |
/** @var \DOMElement $listItem */ | |
$listItem = $dom->createElementNS(XML_NAME_SPACE, 'listItem'); | |
$listItem->setAttribute('index', $i); | |
$list->appendChild($listItem); | |
$subElement = $dom->createElementNS(XML_NAME_SPACE, 'alpha'); | |
$subElement->appendChild($dom->createTextNode(uniqid('a', true))); | |
$listItem->appendChild($subElement); | |
} | |
return $dom; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment