Skip to content

perf(tinybench): batch fast walltime invocations into rounds - #117

Draft
not-matthias wants to merge 14 commits into
mainfrom
cod-4104-batch-fast-tinybench-walltime-benchmarks-into-1-ms-rounds
Draft

not-matthias wants to merge 14 commits into
mainfrom
cod-4104-batch-fast-tinybench-walltime-benchmarks-into-1-ms-rounds

Conversation

@not-matthias

Copy link
Copy Markdown
Member

TLDR: Batch fast Tinybench walltime calls into approximately 1 ms rounds to reduce timer and sample-processing overhead (stacked on #101).

  • Estimate batch size from warmup, or calibrate after lifecycle setup when warmup is disabled. Later forks reuse the first fork's size.
  • Normalize CodSpeed latency statistics per invocation; keep total measured time unscaled. Samples describe batch averages, not individual-call tails.
  • Preserve sequential async calls. Per-invocation hooks and task concurrency stay unbatched; fallback, simulation, and Vitest measurement behavior are unchanged.

Local iterative Fibonacci(10), Node 24.22.1 / Tinybench 4.0.1, 1 s measurement + 100 ms warmup per process, one run per configuration:

Mode Elapsed before → after Samples before → after
Shared process 20.06 s → 1.11 s 28,006,582 → 891
Two forks 59.39 s → 10.33 s 58,596,190 → 1,760

Peak RSS of a measuring child in the two-fork run: 3,769 MiB → 71 MiB. Local smoke checks also cover Tinybench 6.2.2, lifecycle hooks, slow rounds, concurrency, fallback, and simulation.

Closes COD-4104.

@codspeed

codspeed Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Merging this PR will regress 4 benchmarks

5 warnings, 1 note

⚠️ Walltime results may be unreliable

Some benchmarks used the Walltime instrument outside CodSpeed Macro Runners, which can make the results inconsistent.

Learn more about Macro Runners

See affected benchmarks

⚠️ Unable to measure the execution of 8 benchmarks

These benchmarks measured no execution time, so their results are not comparable and count as unchanged. This usually happens when the compiler removes the code under test.

Prevent compiler optimizations

See affected benchmarks

⚠️ 14 benchmarks are dominated by system calls

System calls cannot be simulated consistently and are left out of the measure. The reported value understates the real cost. Switch to the Walltime instrument to measure them.

Learn more about system calls

See affected benchmarks

⚠️ 7 benchmarks with a significant change ran on different hardware

Their base and head results were measured on machines with a different CPU, core count or memory, so the changes might not come from the code. Run base and head on the same runner type.

Learn more about Macro Runners

See affected benchmarks

⚠️ 7 benchmarks with a significant change ran in a different software environment

Their base and head results were measured with a different OS or toolchain, such as compiler, runtime or library versions, so the changes might come from this difference rather than from the code. Open an affected benchmark to see what changed.

See affected benchmarks

ℹ️ 16 benchmarks have no flamegraph

The flamegraph wasn't generated: most of the time was spent in runtime internals, which would leave nothing useful to analyze.

See affected benchmarks

⚡ 25 improved benchmarks
❌ 4 regressed benchmarks
✅ 240 untouched benchmarks
⏩ 57 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
❌ CPU Simulation wait 500ms 26.7 ms 38.4 ms -30.59%
❌ CPU Simulation wait 1sec 53.5 ms 72.9 ms -26.68%
❌ Memory one 1.5 KB 2 KB -26.19%
❌ Walltime fibo darwin 7.9 ms 8.8 ms -10.39%
Walltime switch 2 30 ns < 1 ns ×130
Walltime switch 2 30 ns < 1 ns ×130
Walltime switch 2 30 ns < 1 ns ×130
Walltime switch 1 30 ns < 1 ns ×130
Walltime switch 2 30 ns < 1 ns ×130
Walltime switch 1 30 ns < 1 ns ×130
Walltime switch 1 30 ns < 1 ns ×130
Walltime switch 1 30 ns < 1 ns ×130
⚡ Walltime test_iterative_fibo_10 30 ns 1.9 ns ×16
⚡ Walltime test_iterative_fibo_10 30 ns 1.9 ns ×16
⚡ Walltime test sync baz 10 30 ns 2.6 ns ×12
⚡ Walltime test sync baz 10 30 ns 2.8 ns ×11
⚡ Walltime test_iterative_fibo_100 60 ns 26.7 ns ×2.2
⚡ Walltime test_iterative_fibo_100 60 ns 26.9 ns ×2.2
⚡ CPU Simulation wait 500ms 54.8 ms 29.2 ms +87.53%
⚡ Walltime test sync baz 100 40 ns 22.5 ns +77.99%
... ... ... ... ... ...

ℹ️ Only the first 20 benchmarks are displayed. Go to the app to view all benchmarks.

Tip

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


Comparing cod-4104-batch-fast-tinybench-walltime-benchmarks-into-1-ms-rounds (38afc2a) with cod-3960-implement-process-isolation-in-codspeed-node (2e87449)

Open in CodSpeed

Footnotes

  1. 57 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@not-matthias
not-matthias added this pull request to stack #118 November 4, 2026 10:12
@not-matthias
not-matthias force-pushed the cod-3960-implement-process-isolation-in-codspeed-node branch from 5a0c4db to d172321 Compare November 4, 2026 16:19
Switch codspeed-walltime and electron-e2e from codspeed-macro to
codspeed-macro-x64-ryzen-9950x-ubuntu-24-04.
Drop the v4.17.7-alpha.2 pin. Current runner releases still support the
samply walltime profiler.
Benchmarks in one process share allocator and JIT state, and rounds within
one process are correlated, so a single process gives a biased view of a
benchmark. Add the building blocks for integrations to run each walltime
benchmark in several fresh processes (forks) and pool their rounds:

- `walltimeIsolation(forks?)` picks the mode from the env: parent, fork
  (`CODSPEED_ISOLATED_BENCHMARK`), or one shared process when
  `CODSPEED_PROCESS_ISOLATION=false`
- the fork count is `CODSPEED_WALLTIME_FORKS`, else the integration's
  `forks` option, else 3
- `runForks`/`runForksSync` re-run the benchmark command (keeping the V8
  flags) once per fork and collect the samples each fork writes with
  `writeForkSamples`; a failing fork's exit code is passed on
- `samplesToResult` builds tinybench-style statistics over the pooled
  samples

Refs COD-3960
`withCodSpeed(bench, { forks })` sets the fork count of walltime runs, and
`CODSPEED_WALLTIME_FORKS` overrides it. The parent runs each task in its
forks and reports their pooled rounds; a fork runs only its task, hands its
samples over and prints no banner or summary. Simulation runs are unchanged.

Refs COD-3960
With Vitest 5, each walltime benchmark runs in fresh `vitest bench`
processes restricted to its file. The fork count resolves as
`CODSPEED_WALLTIME_FORKS`, the benchmark's or run's `forks` option,
`codspeedPlugin({ forks })`, then 3. The test timeout is scaled by the
env or plugin fork count, since every fork of a test runs within it.

Vitest's own report shows zeroed statistics for forked benchmarks; the
CodSpeed results hold the pooled rounds. Vitest 3/4 don't fork.

Closes COD-3960
Calibrate approximately 1 ms rounds from warmup and share the iteration count across isolated forks. Normalize latency statistics per invocation while retaining raw total time. Keep per-invocation hooks and concurrent tasks unbatched, and cover shared, forked, synchronous, and asynchronous execution.
@not-matthias
not-matthias force-pushed the cod-3960-implement-process-isolation-in-codspeed-node branch from 18f0083 to 2e87449 Compare November 5, 2026 14:33
@not-matthias
not-matthias force-pushed the cod-4104-batch-fast-tinybench-walltime-benchmarks-into-1-ms-rounds branch from cfed9fe to 38afc2a Compare November 5, 2026 14:33
@not-matthias
not-matthias removed this pull request from stack #118 November 5, 2026 14:34
@not-matthias
not-matthias added this pull request to stack #120 November 5, 2026 14:34
@not-matthias
not-matthias force-pushed the cod-3960-implement-process-isolation-in-codspeed-node branch 2 times, most recently from d51f2ba to 60d0515 Compare November 6, 2026 16:37
@not-matthias
not-matthias removed this pull request from stack #120 November 6, 2026 16:58
Base automatically changed from cod-3960-implement-process-isolation-in-codspeed-node to main November 6, 2026 17:01
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