Skip to content

bench(signals): amortize projection-root-write over 20 commits per body - #3435

Merged
ryansolid merged 1 commit into
nextfrom
bench/projection-root-write-amortize
Sep 14, 2026
Merged

ryansolid merged 1 commit into
nextfrom
bench/projection-root-write-amortize

Conversation

@ryansolid

Copy link
Copy Markdown
Member

Bench hygiene, no runtime change. Follow-up to the CodSpeed investigation on #3431.

Why

tests/store/projection-root-write.bench.ts runs three benchmarks in one process over one set of 20k-key fixtures, and each body performed one commit. V8 emits a one-off ~100k-instruction tier-up chunk that attaches to whichever JS frame is running when it fires, and it lands in exactly one of the three windows. At ~540k Ir per root write that is 16–20% of a window — and it moves between windows on unrelated changes.

CodSpeed's bisection of #3431 (instruction counts, reproducible to ±2):

build ROOT key (#3352) NESTED (untouched) store setter (untouched)
next 537,655 180,890 513,411
#3431 (~300 Ir on its own path) 623,679 181,599 513,424
next + a provably no-op extra call 508,044 (−5.5%) 181,705 627,428 (+22%)

Every reactive-graph symbol in the window was bit-identical between base and head; the delta is the chunk relocating. The flame graph attributed it to recompute self-time via JIT code-range aliasing, which is why it looked like a real regression at first.

Change

Each body runs COMMITS = 20 commits. The chunk amortizes to <1% of a window — under the 5% gate — and the three benchmarks stay per-commit comparable, which is the parity the file guards (#3352 derive vs #3044 setter floor). Absolute numbers re-baseline ×20 on the CodSpeed dashboard; the comment in the file records why.

Locally (vitest bench): ~39 µs / 20 commits for the root write, ~2 µs per commit — same per-commit floor as before.

Co-authored-by: Claude via Cursor noreply@cursor.com

Three benchmarks share one process and one set of 20k-key fixtures, and
each body performed a single commit. V8 emits a one-off ~100k-instruction
tier-up chunk that attaches to whichever frame is running when it fires and
lands in exactly one of the three windows — at ~540k Ir per root write that
is 16-20% of a window, and it moves between windows on unrelated changes.
CodSpeed's bisection of #3431 (2026-09-14) made this exact: a change costing
~300 instructions on its own path read as -8.9% on the root write and x2.4
on the untouched nested write; a provably no-op extra call added to `next`
read as -5.5% on the root write and +22% on the untouched store setter
(537,655 → 508,044 and 513,411 → 627,428 Ir; every reactive-graph symbol
bit-identical).

Each body now runs COMMITS = 20 commits. The chunk amortizes to <1% of a
window — below the 5% gate — and the three stay per-commit comparable,
which is the parity this file guards (#3352 derive vs #3044 setter floor).
Absolute numbers re-baseline ×20.

Co-authored-by: Claude via Cursor <noreply@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@changeset-bot

changeset-bot Bot commented Sep 14, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 2d2a190

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 34892248743

Coverage remained the same at 71.842%

Details

  • Coverage remained the same as the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 1007
Covered Lines: 772
Line Coverage: 76.66%
Relevant Branches: 790
Covered Branches: 519
Branch Coverage: 65.7%
Branches in Coverage %: Yes
Coverage Strength: 15.07 hits per line

💛 - Coveralls

@ryansolid
ryansolid merged commit efcaeba into next Sep 14, 2026
6 checks passed
@codspeed

codspeed Bot commented Sep 14, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 61.38%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

❌ 3 regressed benchmarks
✅ 157 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
projection derive: write one NESTED field (reference) 523.8 µs 2,525.2 µs -79.26%
projection derive: delete + set one ROOT key (#3352) 455.3 µs 1,309.3 µs -65.22%
createStore setter: delete + set one root key (#3044 overlay) 436.8 µs 547 µs -20.14%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing bench/projection-root-write-amortize (2d2a190) with next (25c5064)1

Open in CodSpeed

Footnotes

  1. No successful run was found on next (c3ae310) during the generation of this report, so 25c5064 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

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.

2 participants