Skip to content

perf(assembler): 1.5x faster parse_asm -- 33% less assemble time - #60

Open
dexhunter wants to merge 1 commit into
sql-hkr:mainfrom
dexhunter:perf/parse-asm-skip-disp-regex
Open

dexhunter wants to merge 1 commit into
sql-hkr:mainfrom
dexhunter:perf/parse-asm-skip-disp-regex

Conversation

@dexhunter

Copy link
Copy Markdown
Contributor

TL;DR

  • This PR makes parse_asm in src/tiny8/assembler.py faster. Every assemble() call and every compile_c -> assemble test uses it.
  • It runs the displacement regex only on lines that contain a +. It also builds the X/Y/Z register map once per call.
  • Measured parse time for the test-suite listings (median of 9 paired timings): 58.1 ms -> 39.1 ms, 32.7% faster.
  • pytest tests passes (342 passed). ruff check and ruff format --check are clean.

What & Why

Before, parse_asm called re.sub on every instruction line. Most lines have no +, so the regex can never match there. The code also built the {"X": 26, "Y": 28, "Z": 30} dict again for each X/Y/Z operand.

Now the code checks "+" in line first and uses the compiled pattern only when it is true. It builds the register map once, before the loop. The pattern needs a literal +, so skipping lines without one gives the same result. p.upper() in reg_map is true for exactly the same operands as p.upper() in ("X", "Y", "Z"). The program, labels, pc_to_line and errors stay identical.

Results

Rows 1-3: best of 15 timing repeats, median of 3 alternating rounds. Row 4: median of 9 paired before/after timings. Same machine and Python 3.12:

Situation Before After Change
Compiled C program (compile_c output, 154 lines) 0.268 ms 0.169 ms 36.8% faster
All examples/*.asm programs 136.0 ms 83.9 ms 38.3% faster
Listing where every line has a Y + n / Z+n displacement (400 lines) 0.988 ms 0.862 ms 12.7% faster (regex still runs; no slowdown)
C test-suite listings + test snippets (109 listings, median of 9 paired timings) 58.1 ms 39.1 ms 32.7% faster

Why this is safe and easy to maintain

The change is 9 lines in one function and uses plain Python. The regex is still the same, and lines without a + skip it because it cannot match them. tests/test_assembler.py, tests/test_compiler.py, tests/test_control_flow.py and tests/test_cpu_edge_cases.py cover labels, comments, displacement operands and bad operands.

Validation

  • pytest tests: 342 passed on this branch (342 passed on main).

  • ruff check src/tiny8/assembler.py and ruff format --check src/tiny8/assembler.py: clean.

  • Before/after timing: the suite listings above took 58.1 ms -> 39.1 ms (32.7% faster, 1.49x) in the median of 3 separate measurements. The 3 measurements gave 0.679, 0.671 and 0.673 of the main time. An automated output check compared programs, labels, pc_to_line, source_lines and error messages with main, and they were identical.

  • Quick reproduction:

    python -m timeit -s "import glob; from tiny8 import assemble; srcs = [open(f).read() for f in glob.glob('examples/*.asm')]" "[assemble(s) for s in srcs]"

AI assistance

Code candidates were generated by Codex (gpt-6.1-sol) and tracked with Weco Observe. This PR uses the smallest readable candidate. The tests, timings and an automated output-equality check above were run on it.

Weco share link: https://dashboard.weco.ai/share/gLEKWXkUReYHkIjz2BXzPLKDXaEHdYK2

Run the displacement regex in parse_asm only on lines that contain
a '+' (the pattern needs one to match), and build the X/Y/Z register
map once per call instead of once per operand. Output is unchanged.

Parse time for the C test-suite listings: 58.1 ms -> 39.1 ms (1.49x).

Co-Authored-By: Aiden <aiden@weco.ai>
@codecov

codecov Bot commented Oct 31, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant