Skip to content

Benchmarks

hyperlark builds its parse tables at runtime (like chevrotain and tree-sitter) — it does not generate code. So its natural peers are other runtime parsers, not codegen parsers (nom, lalrpop, pest) or specialized native parsers (JSON.parse), which sit in their own tiers. Every measurement is like-for-like: each parser produces and reads the same value (the JSON object, or the evaluated calc result) through its natural pipeline.

For a per-language, head-to-head comparison against the main parsing libraries — what each one is, its trade-offs, and when to prefer it — see Alternatives, which charts hyperlark’s LALR and Earley engines against the field in Rust, Python, JS, and C.

The Python hyperlark is the PyO3 binding over the same Rust core: you call it from Python, but the parse runs in native code — only your transformer callbacks cross back. So its peers are the other Python parsing libraries. Every one here computes the same scalar (JSON: the sum of truncated numbers; calc: the evaluated result) and the outputs are compared, with any disagreement reported, so the times are like-for-like.

Both engines, one chart. hyperlark’s LALR and Earley appear together so you can see what the general engine costs you. lark’s own Earley is left out here — at 1056 and 1568 ms it would flatten everything — and gets its own comparison at the bottom of this tab.

JSON → value (Python, 134 KB)
hyperlark (LALR) 4.85 ms
sly 43.4 ms
lark (LALR) 52.6 ms
hyperlark (Earley) 66.1 ms
parsimonious (PEG) omitted at 201 ms — it would flatten the chart; it is in the table, and in the Earley comparison at the foot of this tab.
calc → number (Python, 85 KB)
hyperlark (LALR) 7.05 ms
sly 39.8 ms
hyperlark (Earley) 69.5 ms
lark (LALR) 70.8 ms
parsimonious omitted at 127 ms, for the same reason.

lark is the pure-Python reference implementation hyperlark reimplements — the parity baseline, on the same grammars. sly is a yacc-style LALR generator that reduces straight to a value, so every library here is measured that way: an embedded transformer, no tree on either side. The three are doing the same shape of work. parsimonious is a PEG library — general, and charted with the other general engines at the foot of this tab. hyperlark wins because the parse itself is native Rust.

Every library, both workloads (ms; JSON 134 KB, calc 85 KB — the bench corpus):

libraryJSON → valuecalc → number
hyperlark (LALR)4.857.05
sly43.439.8
lark (LALR)52.670.8
hyperlark (Earley)66.169.5
parsimonious (PEG)201127
lark (Earley)10561568

These are hyperlark’s default configuration — opt-in switches (fast_scan) widen the gap further on scan-heavy inputs. Reproduce with bindings/python/bench/bench_cli.py, which also checks every library against hyperlark’s result and reports any that disagrees (lark 1.3.1, CPython 3.14.4).

Construction is faster on every grammar, by 1.7× to 5.6×. The widest margin is on python, much the largest grammar here, where table construction dominates — but size alone does not order the rest, and the 85-byte escaped grammar gains more than either mid-size one:

Grammar (LALR)hyperlarklarkratio
JSON2.74 ms4.66 ms1.7×
calc2.02 ms4.18 ms2.1×
escaped-string0.72 ms2.42 ms3.4×
Python (python.lark)45.5 ms255 ms5.6×

From the same sweep as the parse figures above (_results/python.json), so these are one run on one machine — trust the shape rather than the digits. Construction matters most for short-lived processes, where lark pays for table construction on every start.

Both engines above are compared against lark’s LALR, which is the conservative reading. Engine for engine, against the Earley that lark runs by default — with parsimonious between them as a yardstick, since a general PEG library is the kind of thing people reach for when they want this much generality:

JSON → value · the general engines (134 KB)
hyperlark (Earley) 66.1 ms
parsimonious (PEG) 201 ms
lark (Earley) 1056 ms
calc → number · the general engines (85 KB)
hyperlark (Earley) 69.5 ms
parsimonious (PEG) 127 ms
lark (Earley) 1568 ms
16.0× and 22.5× against lark's Earley; 1.8–3.0× against parsimonious. Earley is the general engine on both sides, so this is the like-for-like default comparison — but LALR is the engine most users should reach for.

Parse a corpus on your own hardware — run it in your browser. Treat those numbers as “how it feels here,” not an authoritative leaderboard — browsers coarsen timers and JIT warmup varies, so the controlled numbers above remain the reference.