Skip to content

Fix quadratic rendering time for many inline links - #1621

Draft
aryansk wants to merge 2 commits into
Python-Markdown:masterfrom
aryansk:codex/fix-quadratic-inline-links
Draft

Fix quadratic rendering time for many inline links#1621
aryansk wants to merge 2 commits into
Python-Markdown:masterfrom
aryansk:codex/fix-quadratic-inline-links

Conversation

@aryansk

@aryansk aryansk commented Aug 11, 2026

Copy link
Copy Markdown

Description

Rendering a paragraph containing many inline links took quadratic time:
each match replaced the link with a placeholder and then rescanned the
whole remaining text from index 0, so N links cost O(N²) pattern work.
'[link](x)' * 8192 took ~7s before this change and ~0.3s after.

__applyPattern now returns the index just past the inserted placeholder
so the next scan starts at the unprocessed tail.

Fixes #1619.

AI Assistance Disclosure

  • If AI tools were used, I have disclosed which ones, and fully reviewed and verified their output.

Claude (via Command Code) assisted with implementation and testing; the change was fully reviewed and verified by a human.

Checklist

  • This PR follows the contribution guidelines.
  • The code follows the Code Style Guide.
  • The commit message follows the Commit Message Style Guide.
  • I have added or updated relevant docs, including release notes if applicable.
  • I have added or updated relevant tests.
  • I have not requested, and will not request, an automated AI review for this PR.

Scanning from index 0 after every inline-pattern match rescanned the
unprocessed text repeatedly, making conversion quadratic in the number
of inline elements. Return the index just past the inserted placeholder
so the next scan starts at the unprocessed tail.

Fixes Python-Markdown#1619.

@waylan waylan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this. I have a few concerns as outlined below.

Comment thread tests/test_syntax/inline/test_links.py Outdated

@waylan waylan Aug 11, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes the API for all inline patterns and processors. @facelessuser I think you have a better handle on this part of the code. Any input on that change here?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I kept the search-index behavior change and documented it under Unreleased > Changed in b745bba, treating it as an inline-processor API/behavior change rather than a Fixed-only entry.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do have some mild concerns about this change. We are assuming that because the API changed here without breaking things, others using this API won't be broken.

When we changed the API here in the first time, we did so in a way that was non-breaking, one you could opt into. This was done by providing a different class that could be checked.

It is possible that we may need to employ some method ot indicate this is a different version of the new way. I really need to do some testing to understand the implications of the change. I will have to do some testing with this over in Pymdown Extensions, where we have a number of plugins using the new style, so I can get a better idea of what the impact here is.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that all the tests over on Pymdown Extensions passed with these changes, so that is a good sign.

Comment thread docs/changelog.md Outdated
@aryansk

aryansk commented Aug 11, 2026

Copy link
Copy Markdown
Author

Thanks for the detailed review. Commit b745bba addresses the points raised: it removes the wall-clock regression test, replaces it with a deterministic search-offset assertion, and moves #1619 under Unreleased > Changed to document the inline-processor behavior/API impact. The full unittest suite passes with 1,089 tests and 13 skipped; changed-file flake8 and git diff --check pass.

@waylan
waylan requested a review from facelessuser August 11, 2026 15:47
@waylan

waylan commented Aug 11, 2026

Copy link
Copy Markdown
Member

Thank you for addressing my concerns. I am going to let @facelssuser review this as he has a better grasp of the affected code.

@aryansk

aryansk commented Aug 12, 2026

Copy link
Copy Markdown
Author

Thanks, @waylan. I appreciate the follow-up; I’ll wait for @facelssuser’s review of the affected code.

@facelessuser

Copy link
Copy Markdown
Collaborator

I will hopefully get to this sometime this week. I've become somewhat exhausted with the onslaught of everyone pointing AI at every project on the internet. I'm already dealing with similar issues on numerous projects I support.

@aryansk

aryansk commented Aug 12, 2026

Copy link
Copy Markdown
Author

Understood. I will leave the draft unchanged while you assess it; no further follow-up is needed from me right now.

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.

Super-linear (quadratic) rendering on many inline links: '[link](x)' * N

4 participants