SEXP Benchmark Strategy
SkillMediaLets your agent benchmark the speed and memory of S-expression parsing stages on KiCad PCB files.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the SEXP Benchmark Strategy skill
About this capability
Design circuit boards with code! ✨ Get software-like design reuse 🚀, validation, version control and collaboration in hardware; starting with electronics ⚡️
What this skill tells your AI
The instructions your AI receives, as published by atopile/atopile in .claude/skills/sexp_bench/SKILL.md and read by ahel’s review.
Goal
Measure and improve S-expression pipeline performance with a focus on:
- Throughput per stage
- Peak memory per stage
- End-to-end behavior on realistic KiCad PCB inputs
Pipeline Stages
Benchmark these layers separately:
tokenizerastparser(typed decode)encode(typed encode to raw SEXP)pretty(formatting)
Dataset Dimensions
Use a matrix over:
depth: shallow vs deep nestingsize: small, medium, large
Recommended size buckets:
small:< 64 KiBmedium:64 KiB .. < 1 MiBlarge:1 MiB .. < 10 MiB
Measurement Model
For each stage and sample:
mean_msand percentile latency (median,p80)mem_before,mem_after,mem_deltastage_peak_increment(stage-local high watermark increase)cumulative_pipeline_peakandcumulative_peak_over_start
Key interpretation:
- Negative/near-zero
mem_deltacan still coexist with highstage_peak_increment. - For allocator-heavy code,
peakmetrics are more informative than final deltas.
Methodology
- Warm caches with warmup runs.
- Run at least one measured sample per cell (more for stable comparisons).
- Keep run settings fixed when comparing commits:
- same machine
- same optimize mode
- same dataset generator/inputs
- Compare both synthetic matrix and a large real-world board.
E2E Roundtrip Benchmark (panel.kicad_pcb)
Use this when validating real end-to-end impact (load -> dump -> reload) on a large board.
Setup
- Build
pyzig_sexp.soin each checkout you want to compare:
source .venv/bin/activate
cd src/faebryk/core/zig
python -m ziglang build python-ext -Doptimize=ReleaseFast -Dpython-include=/usr/include/python3.14 -Dpython-lib=python3.14
- For baseline vs current comparison, create a detached worktree for baseline:
git worktree add /tmp/atopile_pre_tokenizer_fix <baseline_commit>
- Run the benchmark sequentially (not in parallel) to avoid cross-run CPU contention.
Runner Pattern
Use Python with direct importlib loading of pyzig_sexp.so from each checkout. This avoids accidental rebuilds and keeps the comparison tied to the compiled artifact in that checkout.
from pathlib import Path
from time import perf_counter
import gc, importlib.util, sys
spec = importlib.util.spec_from_file_location(
"pyzig_sexp",
"src/faebryk/core/zig/zig-out/lib/pyzig_sexp.so",
)
mod = importlib.util.module_from_spec(spec)
sys.modules["pyzig_sexp"] = mod
spec.loader.exec_module(mod)
text = Path("panel.kicad_pcb").read_text(encoding="utf-8")
# warmup
obj = mod.pcb.loads(text)
out = mod.pcb.dumps(obj)
obj2 = mod.pcb.loads(out)
del obj, out, obj2
gc.collect()
runs = []
for _ in range(5):
gc.collect()
t0 = perf_counter()
obj = mod.pcb.loads(text)
t1 = perf_counter()
out = mod.pcb.dumps(obj)
t2 = perf_counter()
obj2 = mod.pcb.loads(out)
t3 = perf_counter()
runs.append((t1 - t0, t2 - t1, t3 - t2, t3 - t0))
del obj, out, obj2
print("AVG", " ".join(f"{sum(r[i] for r in runs)/len(runs):.3f}" for i in range(4)))
Report Format
Report at minimum:
load_avg_sdump_avg_sreload_avg_stotal_roundtrip_avg_s- relative delta vs baseline (%)
Optimization Approach
Prioritize stage-local wins first, then validate global effects:
- Eliminate avoidable intermediate allocations.
- Use streaming write paths for encode-heavy workloads.
- Keep fast parse paths for success cases; fallback to richer diagnostics on error.
- Re-check correctness via roundtrip and file-format tests after each change.
Safety Checks
After each optimization pass:
- Build release artifacts.
- Run KiCad file-format tests.
- Run representative load-transform-dump flows.
- Re-run matrix + panel benchmark snapshots.
Reporting
Summarize gains in two views:
- Matrix view:
(depth, size) x stage - Large-board view: stage timing + peak memory
Always report:
- absolute values
- speedup ratios
- peak-memory deltas vs baseline
Signals
- GitHub stars
- 4k
- Forks
- 234
- Last commit
- Jun 2026
Advanced
- Catalog kind
- skill
- Gateway key
sexp-bench- Source
- github.com/atopile/atopile