Repository navigation
[6.x] Faster YAML parsing - #15838
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Symfony writes an indentation indicator (e.g. |2-) when a multi-line value's first line starts with spaces, which previously made the whole document fall back to Symfony. These blocks are now handed to Symfony on their own, like |+ blocks already are. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Symfony treats a form feed or Unicode whitespace (such as a non-breaking space) after a dash as a sequence separator, so the fast parser could return different data or skip Symfony's errors for hand-edited content containing them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A 36 character value of hex digits and dashes with a dash at offset 8 could still be numeric to Symfony, such as 1234567e-123456789012345678901234567, which it reads as a float. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both cases used the same provider key, so the first was overwritten and never ran. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Parsing YAML is one of the biggest costs of building the Stache. symfony/yaml parses nested blocks recursively: for each nested block it collects that block's lines and parses them again with a new parser. Every line is scanned once per level of nesting, which makes deeply nested content like Bard slow, and memory-hungry.
This PR adds
Statamic\Yaml\FastParser, whichYaml::parse()now uses. It walks the lines once, descending into each nested block as it meets it.Inlineparser, so it's interpreted exactly as symfony would interpret it.|and|-blocks are read directly. Anything awkward is handed to symfony as a small document of its own.Built together with @DanielDarrenJones.
Speed
paths()build)Peak memory while parsing
The parsed result is identical, so memory held after parsing is unchanged; these are the temporary peaks during the parse. On the real site, 99.4% of files took the fast path, and the rest fell back to symfony/yaml at its normal speed.
Correctness
No differences from symfony/yaml 8.1.5 were found in any of these, including invalid YAML, where both must throw the same error:
ParserTest, routed through the fast parserCases the fuzzing found are deliberately left to symfony. These include an unindented list after a blank line, malformed flow collections like
[1{2], deep nesting (symfony applies its own limit), and a symfony/yaml 8.1 quirk where a nested|block followed by one last line of front matter loses its final newline.The new
FastParserTestcompares every result with symfony's rather than with hard-coded values. It covers hand-picked edge cases, a check that Statamic-dumped content stays on the fast path, and seeded fuzz tests that compare against whichever symfony/yaml version is installed.Notes
🤖 Generated with Claude Code