Skip to content

perf: parallel-producer spike + bank the serial collision win - #13

Merged
jakeklassen merged 4 commits into
mainfrom
perf/parallel-producer-spike
Oct 14, 2026
Merged

jakeklassen merged 4 commits into
mainfrom
perf/parallel-producer-spike

Conversation

@jakeklassen

Copy link
Copy Markdown
Owner

What

Completes the parallel-producer spike (brief in packages/perf-proofs/src/worker/SPIKE.md): can objecs gain CPU performance from Worker threads + shared read-only snapshots for producer-only systems, using shmup collision as the probe — without any public API change.

It also banks the single-threaded win the spike uncovered, and fixes an unrelated pre-existing lint failure so CI is green.

Commits

  1. chore: bump node 26.11.1 / pnpm 12.12.1 (mise.toml)
  2. perf(examples): hoist AABB bounds out of the inner loop and inline the intersection test in the shmup collision system — removes 4 temp-object allocations per pair check. Selected pairs and emitted events are unchanged (asserted by the parity harness below).
  3. test(perf-proofs): the full spike — three serial kernels, a persistent SAB worker pool, the end-to-end benchmark matrix, and a correctness gate that aborts rather than reporting timings for incorrect kernels.
  4. fix(examples): rollupOptions → rolldownOptions (Vite 8 / rolldown); clears the type-aware oxlint error that was failing pnpm lint.

Findings (AMD Ryzen 9 7950X3D, Node 26)

  • Single-threaded packed cleanup is ~10× over the shipped collision kernel, every scenario and size. Mostly from killing per-pair temp allocations + hoisting bounds. No threads, no API change. (Commit 2 applies the readable ~2.5× slice of this to the demo.)
  • SAB workers add a further 2.5–5.5× only at large-N, low collision density (no-hit/sparse, n≥1024); crossover vs best serial ≈ n=512.
  • Dense collisions lose at every size (0.24–0.50×) — emit-all-candidates forfeits the serial greedy early-break.
  • Barrier floor ~68 µs (1W) → ~102 µs (4W). Pack is ~16 ns/collider (negligible). Wins need an async frame barrier, which Scene.update() doesn't have today.

Recommendation: qualified go, narrow scope. Bank the serial win (done here); real parallel payoff is for large-N low-density read-only producers (AI sensing / visibility / procgen), not collision — a spatial broadphase beats both for collision. Full writeup + answers to the brief's 10 questions in packages/perf-proofs/src/worker/README.md.

Verification

pnpm lint ✅ · pnpm --filter objecs build ✅ · pnpm --filter objecs check-exports ✅ · objecs tests 25 pass ✅ · perf-proofs typecheck ✅ · examples tsc ✅ · worker parity gate green (84 fixture/worker combinations).

No public objecs API change. 🤖 Generated with Claude Code

jakeklassen and others added 4 commits October 13, 2026 21:01
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Hoist the outer entity's AABB bounds out of the inner loop (the previous
version recomputed them for every otherEntity) and inline the rectangle
intersection test, which removes the two temp AABB object literals (four
allocations) built on every pair check. Drops the now-unused intersects
import.

Selected collision pairs and emitted events are unchanged — this is the
serial/precomputed transformation whose pair-for-pair equivalence to the
original is asserted by the perf-proofs parallel-producer parity harness.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Evidence-based evaluation of Worker threads + shared read-only snapshots
for producer-only systems, using shmup collision as the probe. Adds three
serial kernels (current-object replica, precomputed, packed SoA), a
persistent SAB worker pool, the end-to-end benchmark matrix, and a
correctness gate (cross-kernel parity + hand-derived ground truth) that
aborts rather than reporting timings for incorrect kernels.

Finding: the single-threaded packed cleanup is ~10x; SAB workers add a
further 2.5-5.5x only at large-N low-density, and lose on dense collisions
because emit-all-candidates forfeits the serial greedy early-break. Full
writeup and recommendation in src/worker/README.md; original brief in
src/worker/SPIKE.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Vite 8 runs on rolldown and marks build.rollupOptions deprecated in favor
of build.rolldownOptions (identical shape). Clears the type-aware oxlint
error that was failing the repo-wide `pnpm lint` CI step.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@netlify

netlify Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for objecs ready!

Name Link
🔨 Latest commit 028856b
🔍 Latest deploy log https://app.netlify.com/projects/objecs/deploys/6aced502105bad28c10023c6
😎 Deploy Preview https://deploy-preview-13--objecs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@jakeklassen
jakeklassen merged commit e2d76b0 into main Oct 14, 2026
7 checks passed
@jakeklassen
jakeklassen deleted the perf/parallel-producer-spike branch October 14, 2026 01:06
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