Skip to content

perf: answer the <pre> ancestor check from parent_tags - #273

Open
dugynoo wants to merge 1 commit into
matthewwithanm:developfrom
dugynoo:perf/pre-ancestor-from-parent-tags
Open

perf: answer the <pre> ancestor check from parent_tags#273
dugynoo wants to merge 1 commit into
matthewwithanm:developfrom
dugynoo:perf/pre-ancestor-from-parent-tags

Conversation

@dugynoo

@dugynoo dugynoo commented Aug 24, 2026

Copy link
Copy Markdown

#191 propagated the parent tag context downward so ancestor questions could be answered from
parent_tags instead of walking the tree. One call site in process_tag still walks:

if node.name == 'pre' or node.find_parent('pre'):

parent_tags is in scope and already holds every ancestor tag name, so the same question is a
set lookup:

if node.name == 'pre' or 'pre' in parent_tags:

find_parent runs once per node and walks to the root, which makes conversion O(nodes × depth).
Flat documents never notice, nested ones do.

Measurement

("<div>" * 5000) + ("<b>x</b>" * 40000) + ("</div>" * 5000), 366 KB:

develop with this change
nested 23.39 s 0.34 s
same content, no nesting 0.33 s 0.27 s

The flat case is the floor, so the nesting accounted for all of it.

Equivalence

parent_tags excludes the node itself and so does find_parent, so the separate
node.name == 'pre' test still covers that case.

Output is byte-identical on that input and on 20,000 real-world HTML emails: 0 differences.
The existing suite passes (83 tests), along with flake8 and restructuredtext-lint.

matthewwithanm#191 propagated parent tag context downward to replace ancestor tree
walks. This call site was missed, so process_tag still calls
find_parent('pre') once per node, making conversion O(nodes x depth).

On a 366 KB document nested 5000 deep this takes conversion from
23.39 s to 0.34 s. The same content with no nesting takes 0.33 s
before and 0.27 s after, so the nesting accounted for all of it.

Output is unchanged: parent_tags excludes the node itself, exactly as
find_parent does, and the separate node.name == 'pre' test still covers
that case. Verified byte-identical on 20,000 real-world HTML documents.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant