Skip to content

Commit c367b89

Browse files
committed
perf(zyn_peg): decide an alternative on the byte ahead of it
A choice tried each alternative in turn and unwound whatever the failed one had run. Most of that work was doomed before it started: 82% of the instructions in one parse of the prelude ran inside an alternative later thrown away. Every rule now carries the bytes it can begin with, grown to a fixpoint because rules call each other, and a choice guards each alternative but its last against the byte ahead. An alternative that byte rules out costs one test rather than everything it would have run before failing. Parsing the prelude falls from 21.61 ms to 10.67 ms, ahead in all six interleaved pairs, with user CPU halved. Rule entries drop from 65,844 to 28,400, failed matches from 52,436 to 12,901, and peak memory from 64 to 22 MB, for 266 more instructions in the compiled grammar. Anything the analysis is unsure of reads as any byte, so a guard never skips an alternative that could have matched: a pattern matching the empty string, a negated class, a repetition that skips whitespace first, and a rule the fixpoint leaves with no bytes all turn the guard off rather than narrow it. The 65 files of the corpus parse to the trees the interpreter builds, and the ImagePipe grammar's tests carry the analysis over a second grammar.
1 parent c8c02a9 commit c367b89

2 files changed

Lines changed: 347 additions & 14 deletions

File tree

0 commit comments

Comments
 (0)