Make default HTML conversion allocation-light - #276
Merged
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #276 +/- ##
============================================
- Coverage 92.49% 92.26% -0.24%
- Complexity 3708 3896 +188
============================================
Files 110 111 +1
Lines 10501 10923 +422
============================================
+ Hits 9713 10078 +365
- Misses 788 845 +57 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Outcome
Make ordinary Djot-to-HTML conversion substantially faster without weakening the public AST, extension behavior, or the authoritative parser.
The default facade now attempts a conservative borrowed-source layout for common ASCII documents up to 64 KiB. If the complete document is accepted, it publishes byte-identical HTML without constructing public AST nodes. Any ambiguous or unsupported boundary rejects the entire attempt and re-runs through the existing parser and renderer.
Why this is so much faster
The previous
convert()route always paid for the complete owned pipeline:Documentplus block and inline node objects;HtmlRenderer;That architecture remains the source of truth, but most application traffic does not need an inspectable AST. The new route removes the dominant costs for the common facade call:
The 64 KiB and ASCII limits are deliberate parity boundaries, not parser limits. Rich inline syntax, lazy or ambiguous headings, lists, tables, quotes, Unicode, attributes, profiles, safety modes, warnings, source lines, extensions, listeners, output transformers, custom parser/renderer access, alternate renderers, and explicit
parse()calls all retain the owned AST pipeline.convertFile()now uses the same facade route.Performance
PHP 8.5.9 NTS, CLI OPcache enabled, Node.js 22.22.2, Rust 1.97.1, Go 1.22.2. Warmed in-process trials; 20 measured iterations and 5 warmups. The cross-language runners now generate the exact same paragraph-safe 51,179-byte Djot fixture in every runtime.
So this makes djot-php faster than the reference JavaScript implementation and godjot on the shared common-document workload. Native Rust remains faster.
Against djot-php itself, a separate 57,410-byte representative document measured:
The HTML was byte-identical.
Reproduce the cross-language comparison with:
The benchmark cleanup in this PR also:
cargo runso custom Cargo target directories work;--djot-only.Correctness
Validation