Skip to content

Commit d0d9c8b

Browse files
authored
Optimize xinclude_run_byid by caching elements by xml:id (#300)
1 parent 59621bf commit d0d9c8b

1 file changed

Lines changed: 11 additions & 3 deletions

File tree

configure.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -704,17 +704,25 @@ function xinclude_run_byid( DOMDocument $dom )
704704
// so we need to *simulate* its *recursive* nature here.
705705

706706
$total = 0;
707+
$xpath = new DOMXPath( $dom );
708+
$xpath->registerNamespace( "xi" , "http://www.w3.org/2001/XInclude" );
709+
710+
// Resolve xpointers via a precomputed map; on duplicate xml:ids, first wins.
711+
// Avoids quadratic tree walks (~ 90% performance gain).
712+
$byId = [];
713+
foreach( $xpath->query( "//*[@xml:id]" ) as $node ) {
714+
$byId[$node->getAttribute("xml:id")] ??= $node;
715+
}
716+
707717
for( $run = 0 ; $run < 10 ; $run++ )
708718
{
709-
$xpath = new DOMXPath( $dom );
710-
$xpath->registerNamespace( "xi" , "http://www.w3.org/2001/XInclude" );
711719
$xincludes = $xpath->query( "//xi:include" );
712720

713721
$changed = false;
714722
foreach( $xincludes as $xinclude )
715723
{
716724
$xpointer = $xinclude->getAttribute( "xpointer" );
717-
$target = $xinclude->ownerDocument->getElementById( $xpointer );
725+
$target = $byId[ $xpointer ] ?? null;
718726

719727
if ( $target == null )
720728
continue;

0 commit comments

Comments
 (0)