perf: opt-in first-char dispatch comment-line parser (use_cleri=False) - #45
Merged
Merged
Conversation
After the per-atom tokenizer and the C marshalling, the dominant remaining read cost is parsing the comment line. Profiling showed it is ~92% the libcleri grammar's generic parse-tree machinery (build + re-walk a CST), not regex matching — so a faster parser generator (packcc) tied and a faster allocator (arena) bought ~1%, while a hand-written first-char dispatcher that folds parse+marshal into one pass measured ~1.4-1.8x on the comment line. Add that dispatcher as an opt-in fast path, gated behind use_cleri (default True = libcleri, unchanged behaviour). use_cleri=False selects extxyz_dispatch_parse (libextxyz/extxyz_dispatch.c): it dispatches each value on its first non-space char, validates token extents with the grammar's OWN PCRE2 patterns (same accepted token language by construction), and builds the same DictEntry as tree_to_dict in a single pass. This mirrors the per-atom use_regex=False tokenizer the project already ships: a hand fast path with libcleri kept as the canonical grammar, the pure-Python pyleri oracle, and the fallback. Provability shifts from "by generation" to "by differential test". The flag threads like use_regex: ase-extxyz read_cextxyz -> iread_dicts -> read_frame_dicts -> the C-API read_frame / ctypes extxyz_read_ll_opts (new trailing int arg; ABI-safe — Fortran/Julia bind the 7-arg extxyz_read_ll, which passes use_cleri=1). The dispatcher is pure C + pcre2, compiled into all targets; its regexes are compiled+JIT'd once (eager at import, atexit free). tests/test_dispatch_parity.py asserts bit-identical info/arrays and identical accept/reject vs libcleri over a fixture + 300-line randomized corpus; a USE_CLERI=false conftest axis + CI step run the whole C-backend suite through the dispatcher. Verified: 0 mismatches on all 76,346 MAD comment lines, 0 leaks (incl. the reject path), full ASE read 3.5s -> 2.5s on MAD. Also fixes free_DataLinkedList to free per-node string content on the error path. README: new "Comment-line parser (use_cleri=False)" benchmark table (the win grows from ~1.07x at 2000 atoms/frame to ~1.77x at 5); refreshed the read, tokenizer and write tables + plots on current hardware. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Add 3.14 to the wheel matrix and bump cibuildwheel v2.22.0 -> v4.1.0 (3.14 GA support landed in cibuildwheel 3.0; cp314-* builds the regular interpreter, not the free-threaded cp314t). Add the 3.14 classifier. - New build_sdist job (python -m build --sdist) — meson-python configures the build to make the tarball, so it installs libpcre2-dev and checks out the libcleri submodule. Verified locally: the sdist includes the libextxyz C sources (incl. extxyz_dispatch.c), the libcleri submodule, the grammar, and subprojects/pcre2.wrap, and `pip install`ing it builds and imports with the C read path active. - publish now needs [build_wheels, build_sdist] and attaches/uploads both the wheels and the sdist to the GitHub Release and PyPI. Co-Authored-By: Claude Opus 4.8 (1M context) <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.
What
Add an opt-in first-char-dispatch comment-line parser, gated behind a new
use_cleriflag (defaultTrue, so behaviour is unchanged until opted in).use_cleri=False(C backend only) replaces the libcleri grammar walk for the comment line withextxyz_dispatch_parse(libextxyz/extxyz_dispatch.c).Why
After the per-atom tokenizer (
use_regex=False) and the C marshalling (#44), the dominant remaining read cost is the comment line. A series of measured spikes showed it is ~92% libcleri's generic parse-tree machinery (build + re-walk a CST), not regex matching:So the win can't be had inside
pyleri→libcleri; it needs a leaner parser. This ships that as a fast path — the comment-line analog of the per-atomuse_regex=Falsetokenizer the project already ships.How it stays provable
The dispatcher dispatches each value on its first non-space char and validates token extents with the grammar's own PCRE2 patterns (same accepted token language by construction), building the same
DictEntryastree_to_dict. libcleri is kept as the canonical grammar, the pure-Python pyleri oracle, and the fallback. Provability shifts from "by generation" to "by differential test":tests/test_dispatch_parity.py— bit-identical info/arrays + identical accept/reject vs libcleri over a fixture + 300-line randomized corpus.USE_CLERI=falseconftest axis + a CI step run the whole C-backend suite through the dispatcher.Verification
use_cleri=TrueandUSE_CLERI=false).free_DataLinkedListto free per-node string content on the error path).Safety / ABI
use_clerithreads likeuse_regex(ase-extxyz →iread_dicts→read_frame_dicts→ C-APIread_frame/ ctypes).extxyz_read_ll_optsgains a trailingint use_cleri; ABI-safe — Fortran/Julia bind the 7-argextxyz_read_ll, which passesuse_cleri=1(unchanged). The dispatcher is pure C + pcre2, compiled into all targets; regexes compiled+JIT'd once (eager at import, atexit free; symbols added to both.defs for Windows).Benchmarks (README)
New "Comment-line parser (
use_cleri=False)" table — the win is per-frame, so it grows as frames shrink:Read / tokenizer / write tables + both plots also refreshed on current hardware.
Follow-ups (out of scope)
+HChand-coded-token variant (~1.5× more).use_cleri=Falseonce it has soaked.🤖 Generated with Claude Code