Skip to content

Speed up traversing nodes with node visitors - #4976

Open
nicolas-grekas wants to merge 1 commit into
twigphp:3.xfrom
nicolas-grekas:node-traverser-fast-children
Open

nicolas-grekas wants to merge 1 commit into
twigphp:3.xfrom
nicolas-grekas:node-traverser-fast-children

Conversation

@nicolas-grekas

@nicolas-grekas nicolas-grekas commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

NodeTraverser walks the whole tree once per node visitor, and it iterated over the children of each node with foreach ($node as ...), which allocates an ArrayIterator per node and per visitor. It now reads the children array through a new internal Node::getNodes() method. On the Symfony Demo, where six visitors are registered, walking the 21k nodes of its 52 templates takes half the instructions it took, and warming up its Twig cache runs 15% fewer instructions and takes 520ms instead of 566ms.

The traverser doesn't go through getIterator() anymore, so a subclass overriding it to hide children from visitors would be bypassed, and one declaring its own getNodes() would clash; I found none in Twig, Symfony or UX. Calling getArrayCopy() on the iterator returned by getIterator() would avoid the new method, but it saves 13% of the traversal instructions instead of 50%: new \ArrayIterator() and getArrayCopy() both copy the array.

Merge-up notes

To 4.x: the patch applies as is (I ran the 4.x suite with it), the CHANGELOG entry doesn't go to 4.x.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant