Skip to content

perf: rerun the full benchmark and refresh the published results - #205

Merged
unadlib merged 4 commits into
mainfrom
docs/benchmark-rerun-40f3a42
Oct 12, 2026
Merged

unadlib merged 4 commits into
mainfrom
docs/benchmark-rerun-40f3a42

Conversation

@unadlib

@unadlib unadlib commented Oct 12, 2026

Copy link
Copy Markdown
Owner

Part of #168.

This PR reruns the full benchmark suite on main at 40f3a42, the source after #200, #201 and #202, and replaces every published figure with the results of that one batch. Until now the published results were the batch of #199 at ce0c25e with the shift-and-update cells that #200 measured again; #201 and #202 changed runtime code after both.

  1. Performance summary (perf-testing/reports/SUMMARY.md). Every result, table and limit comes from this batch, including the shared-process control, the process-order control, memory, the Immer plugin datasets and the local budget gate. The "changes since the previous batch" section compares this batch with the previously published cells, with an A/B of the sources of ce0c25e and 40f3a42 for the cells whose comparisons changed. The PR sections of perf: change the copy of a Set draft directly, and keep the changes of a Set draft that left its key #195, perf: read the type of a draft from its state when applying patches #196, perf: find a moved array element's original index from the offset of its move #200 and fix: bound the search for repeated moved array elements and type maybe-async recipes of primitive states #202 keep their comparisons with main, and their cross-library figures come from this batch. The history gains an entry for the batch of perf: rerun the full benchmark on main and refresh the published results #199, and the archive index describes the new one.
  2. README. The headline, the features list, the performance section and its three tables.
  3. Website. The home page figures and features card, the site description, the intro, the performance page and the Comparison with Immer page.
  4. Benchmark guide. The process-order example in the fairness notes.

Bundle sizes are unchanged. Measured the README's way (esbuild 0.24.0, browser ESM, minified, Brotli), create alone bundles to 7,909 bytes and create with apply, current and original to 8,535 bytes, still 7.9 kB and 8.5 kB. size-limit reports 8.64 / 7.58 / 8.52 kB, and size:compare shows no change against the baseline.

Results

Comparator Previously published This batch
Immer 11.1.18 596 / 16 / 2 of 614, 3.59 595 / 13 / 6 of 614, 3.58
Immer with its defaults 154 / 0 / 3 of 157, 6.66 154 / 0 / 3 of 157, 6.63
Mutative 1.3.0 538 / 73 / 3 of 614, 4.29 535 / 70 / 9 of 614, 4.27
Hand-written reducer 18 / 3 / 129 of 150, 0.12 18 / 3 / 129 of 150, 0.12

Cells faster / within 5% / slower, and the geometric mean of comparator time over Mutative time.

  • Headline figures. Matched settings stay at 3.6x. With each library's defaults the figure becomes 6.6x (was 6.7x): 6.63 against 6.66 rounds the other way.
  • Large arrays. 222 of 232 cases at 1,000 and 10,000 rows (4.7x).
  • Moves. Up to 1,052x instead of 1,051x: removing the first of 10,000 rows took 7.04 µs against 7,408 µs for Immer.
  • With patches. Faster than Immer in 148 of 150 cases (3.3x), and 4.6x Mutative 1.3.0.
  • Cells slower than Immer. 6 instead of 2, all with auto-freeze. class-wide-update at 1,000 rows is slower as before. The same scenario without patches at 100 and 10,000 rows moved by less than 2% and crossed the 5% line. add and concat at 100 rows are slower in processes that overlapped those of Immer.
  • Cells slower than Mutative 1.3.0. 9 instead of 3, all with auto-freeze, by 8–18%: add, concat, update-largeObject1 and push-and-insert at 100 rows and object-delete at 1,000 rows. The processes of these cells varied by up to 1.4 times in both batches.

Changes against the previously published cells

Checks

  • The batch ran in a clean worktree of main at 40f3a42 with its own frozen-lockfile install, unchanged before and after. Its production artifact cb6464f3… is byte-identical to a build in the repository. The batch took 7 h 12 min on the M1 Max, and all 21 steps succeeded. Each of the 2,400 timing processes validated its scenarios before timing.
  • The local budget gate (ci.mjs --self-control) passed all 222 decisions of the five groups; latency ratios 0.970–1.109.
  • pnpm benchmark:immer:check validated 1,240 scenario/library/freeze/patch combinations, pnpm test:benchmarks passes (35 tests), and pnpm size passes.
  • The website builds, and its link check passes (49 pages). pnpm format --check passes; on the edited Markdown files, oxfmt --check reports the same table-padding differences as on main.
  • No source, test or harness file changes.
  • The raw datasets stay in the ignored perf-testing/results/2026-10-12/, and the A/B rounds in perf-testing/results/2026-10-12-ab/ and 2026-10-12-ab2/, as for the previous batches. The archive policy's perf-reports-* release was not created.

Commits

  1. perf: record the benchmark of main at 40f3a42 in the performance summary
  2. docs: refresh the README's benchmark figures from the benchmark of 40f3a42
  3. docs: refresh the website's benchmark figures from the benchmark of 40f3a42
  4. docs: refresh the process order example in the benchmark guide

@github-actions

Copy link
Copy Markdown

Coverage after merging docs/benchmark-rerun-40f3a42 into main will be

100.00%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   apply.ts100%100%100%100%
   array.ts100%100%100%100%
   constant.ts100%100%100%100%
   create.ts100%100%100%100%
   current.ts100%100%100%100%
   draft.ts100%100%100%100%
   draftify.ts100%100%100%100%
   error.ts100%100%100%100%
   index.ts100%100%100%100%
   interface.ts100%100%100%100%
   internal.ts100%100%100%100%
   makeCreator.ts100%100%100%100%
   map.ts100%100%100%100%
   original.ts100%100%100%100%
   patch.ts100%100%100%100%
   rawReturn.ts100%100%100%100%
   set.ts100%100%100%100%
   unsafe.ts100%100%100%100%
src/utils
   cast.ts100%100%100%100%
   copy.ts100%100%100%100%
   deepFreeze.ts100%100%100%100%
   draft.ts100%100%100%100%
   finalize.ts100%100%100%100%
   forEach.ts100%100%100%100%
   index.ts100%100%100%100%
   mark.ts100%100%100%100%
   marker.ts100%100%100%100%
   proto.ts100%100%100%100%

@unadlib unadlib changed the title perf: rerun the full benchmark on main at 40f3a42 and refresh the published results perf: rerun the full benchmark on main and refresh the published results Oct 12, 2026
@unadlib unadlib changed the title perf: rerun the full benchmark on main and refresh the published results perf: rerun the full benchmark and refresh the published results Oct 12, 2026
@unadlib
unadlib merged commit 45196fd into main Oct 12, 2026
10 checks passed
@unadlib
unadlib deleted the docs/benchmark-rerun-40f3a42 branch October 12, 2026 11:08
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