benchmark_types.ts

view source

Declarations
#

6 declarations

BenchmarkBudget
#

benchmark_types.ts view source

BenchmarkBudget import type {BenchmarkBudget} from '@fuzdev/fuz_util/benchmark_types.js';

Effective time-budget config used to produce a benchmark sample set. Resolved from per-task overrides on top of suite defaults — what the measurement loop actually saw, not what was configured.

async_resolved captures the boolean that benchmark_warmup actually returned for the measurement run — *not* the user's task.async hint. The two diverge when (a) the hint is undefined and the function is auto-detected sync vs. async, or (b) a conditional-async fn resolves differently between runs. Persisting the resolved value is what makes the budget describe "what the loop saw," not "what was configured."

duration_ms

type number

warmup_iterations

type number

min_iterations

type number

max_iterations

type number

async_resolved

type boolean

BenchmarkConfig
#

benchmark_types.ts view source

BenchmarkConfig import type {BenchmarkConfig} from '@fuzdev/fuz_util/benchmark_types.js';

Configuration options for a benchmark suite.

duration_ms?

Target measurement duration per task in milliseconds. The loop runs at least min_iterations iterations *and* at least this long, with max_iterations and on_iteration abort() as hard ceilings. Default: 1000ms

type number

warmup_iterations?

Number of warmup iterations before actual measurements. Warmup helps stabilize JIT compilation and caches. Default: 10

type number

cooldown_ms?

Cooldown time between tasks in milliseconds. Lets the runtime settle GC and (partially) thermal state between tasks. Fixed regardless of the previous task's duration or allocation footprint — if a suite mixes heavy and light tasks, raise this so light tasks downstream don't run in the prior task's GC shadow. Default: 100ms

type number

min_iterations?

Minimum number of iterations to run. The loop continues past duration_ms if needed to reach this floor, so raising it in a slow suite extends wall-clock past duration_ms.

The default (30) is sized so the Welch's-t DOF approximation used by benchmark_stats_compare stays stable on the floor case. Lowering it below ~15 produces statistically unreliable significance calls on slow tasks that hit the floor exactly — the math still runs but comparison.significant becomes a coin flip on noisy outliers.

Default: 30

type number

max_iterations?

Maximum number of iterations to run. Prevents infinite loops on extremely fast functions, and also sizes the pre-allocated timings array — set this only as high as you expect to fill, since oversized caps waste memory and add GC pressure during measurement. Default: 100000

type number

timer?

Custom timer to use for measurements. Default: timer_default (auto-detects environment)

type Timer

on_iteration?

Callback invoked after each iteration completes. Useful for triggering garbage collection, logging progress, early termination, or custom instrumentation.

Note: The callback time is NOT included in iteration measurements - it runs after the timing capture. However, frequent GC calls will slow overall benchmark execution time.

type (task_name: string, iteration: number, abort: () => void) => void

// Trigger GC between iterations (run node with --expose-gc) new Benchmark({ on_iteration: () => { if (globalThis.gc) globalThis.gc(); } }) // Log progress for long-running benchmarks new Benchmark({ on_iteration: (name, iteration) => { if (iteration % 1000 === 0) { console.log(`${name}: ${iteration} iterations`); } } }) // Stop early when converged new Benchmark({ on_iteration: (name, iteration, abort) => { if (iteration > 1000 && has_stabilized()) abort(); } })

on_task_complete?

Callback invoked after each task completes. Useful for logging progress during long benchmark runs.

type (result: BenchmarkResult, index: number, total: number) => void

new Benchmark({ on_task_complete: (result, index, total) => { console.log(`[${index + 1}/${total}] ${result.name}: ${result.stats.ops_per_second.toFixed(0)} ops/sec`); } })

BenchmarkFormatTableOptions
#

benchmark_types.ts view source

BenchmarkFormatTableOptions import type {BenchmarkFormatTableOptions} from '@fuzdev/fuz_util/benchmark_types.js';

Options for table formatting.

groups?

Group results by category using filter functions.

type Array<BenchmarkGroup>

BenchmarkGroup
#

benchmark_types.ts view source

BenchmarkGroup import type {BenchmarkGroup} from '@fuzdev/fuz_util/benchmark_types.js';

A group definition for organizing benchmark results.

name

Display name for the group

type string

description?

Optional description shown below the group name

type string

filter

Filter function to determine which results belong to this group

type (result: BenchmarkResult) => boolean

baseline?

Task name to use as baseline for the "vs" column. When specified, ratios are computed against this task instead of the fastest. If the baseline task is not found in the group, falls back to "vs Best" with a warning.

type string

BenchmarkResult
#

benchmark_types.ts view source

BenchmarkResult import type {BenchmarkResult} from '@fuzdev/fuz_util/benchmark_types.js';

Result from running a single benchmark task.

name

Task name

type string

stats

Statistical analysis of the benchmark

type BenchmarkStats

iterations

Number of iterations executed

type number

total_time_ms

Total wall-clock time for the task (setup + warmup + measurement + teardown) in milliseconds

type number

timings_ns

Raw timing data for each iteration in nanoseconds. Length equals iterations (the array is right-sized after measurement). Useful for custom statistical analysis, histogram generation, or exporting to external tools.

type Array<number>

budget

Effective per-task time budget after applying overrides to suite defaults. Persisted into baselines so benchmark_baseline_compare can detect methodology drift — a min_iterations bump between baseline and current shifts Welch's DOF and produces "regressions" that are sample-size artifacts, not real drift.

type BenchmarkBudget

BenchmarkTask
#

benchmark_types.ts view source

BenchmarkTask import type {BenchmarkTask} from '@fuzdev/fuz_util/benchmark_types.js';

A benchmark task to execute.

The time-budget fields (duration_ms, warmup_iterations, min_iterations, max_iterations) override the suite-level BenchmarkConfig for this task only. Use them when one task is much faster or slower than the others — e.g. raise min_iterations on a slow task so its percentile/CI math has enough samples without inflating the budget for the fast tasks.

Reading output across overrides: when per-task overrides diverge across rows in the same table, cross-row comparison weakens. Percentiles (p50, p99, …) become unreliable when sample counts differ — p99 at n=30 and p99 at n=50000 estimate different things. Means (and the vs Best column) stay reasonable only if warmup_iterations is held comparable across tasks; asymmetric warmup biases the under-warmed task's mean upward. Per-task percentiles remain valid for that task alone.

name

Name of the task (for display)

type string

fn

Function to benchmark (sync or async). Return values are ignored.

type () => unknown

setup?

Optional setup function run before benchmarking this task. Not included in timing measurements.

Mutations to fn and name made here are honored by the measurement loop — useful for dynamic configuration that depends on async state resolved during setup.

type () => void | Promise<void>

teardown?

Optional teardown function run after benchmarking this task. Not included in timing measurements.

type () => void | Promise<void>

skip?

If true, skip this task during benchmark runs. Useful for temporarily disabling tasks during development.

type boolean

only?

If true, run only this task (and other tasks marked only). Useful for focusing on specific tasks during development.

type boolean

async?

Hint for whether the function is sync or async. Auto-detected during warmup if not set; async: false skips per-iteration promise checking for sync functions, while async: true forces an await on every measurement iteration.

Setting async: true on a function that returns sync forces an unnecessary microtask per iteration — for sub-microsecond functions this adds measurable bias. Prefer leaving async undefined (auto- detected during warmup) unless the conditional-async hazard below applies.

Required for conditional-async fns — without async: true, a first call that happens to return synchronously locks in the sync code path and any later Promise returns leak as unhandled rejections.

type boolean

duration_ms?

Override the suite's duration_ms for this task only. Useful when one task is much slower than others and needs a longer (or shorter) measurement window than the suite default.

type number

warmup_iterations?

Override the suite's warmup_iterations for this task only. Slow tasks may want fewer warmup iterations to keep wall-clock reasonable; tight/complex functions may want more so TurboFan reaches steady state.

type number

min_iterations?

Override the suite's min_iterations for this task only. Raise this on slow tasks so percentile and CI math have enough samples. Wins over duration_ms (see the suite field) — a slow task with a raised floor extends wall-clock until the count is reached.

Prefer raising this over duration_ms when you need more samples: per-iteration noise (GC, scheduler, thermal) is a time-rate process, so a longer wall-clock window proportionally inflates exposure to rare tail events. Raising the sample floor fixes the statistical-power problem without that inflation.

type number

max_iterations?

Override the suite's max_iterations for this task only. Cap a fast task to a fixed sample count, or raise the ceiling on a slow task that would otherwise be limited by the suite default. Also sizes the per-task pre-allocation — avoid extreme caps that won't actually be filled. When this differs sharply across tasks in the same suite, the larger allocation can leak GC pressure into subsequent tasks (cooldown_ms is fixed regardless of prior task footprint).

type number

Depends on
#

Imported by
#