benchmark.ts

Benchmarking library.

@example

import {Benchmark} from '@fuzdev/fuz_util/benchmark.ts'; const bench = new Benchmark({ duration_ms: 5000, warmup_iterations: 5, }); bench .add('slugify', () => slugify(title)) .add('slugify_slower', () => slugify_slower(title)); const results = await bench.run(); console.log(bench.table());
view source

Declarations
#

2 declarations

Benchmark
#

benchmark.ts view source

import {Benchmark} from '@fuzdev/fuz_util/benchmark.js';

Benchmark class for measuring and comparing function performance.

constructor

type new (config?: BenchmarkConfig): Benchmark

config

default {}

add

Add a benchmark task.

type (name: string, fn: () => unknown): this

name

task name or full task object

type string

fn

Function to benchmark (if name is string). Return values are ignored.

type () => unknown
returns this

this Benchmark instance for chaining

bench.add('simple', () => fn()); // Or with setup/teardown: bench.add({ name: 'with setup', fn: () => process(data), setup: () => { data = load() }, teardown: () => { cleanup() }, });

throws

  • Error - if a task with the same name already exists, or if `fn` is missing when `name` is a string

remove

Remove a benchmark task by name.

type (name: string): this

name

type string
returns this

this Benchmark instance for chaining

bench.add('task1', () => fn1()); bench.add('task2', () => fn2()); bench.remove('task1'); // Only task2 remains

throws

  • Error - if task with given name doesn't exist

run

Run all benchmark tasks.

Tasks execute in add() order. The first task runs against a colder runtime than subsequent ones (uncompiled JS, cold caches) — a property of in-process benchmarking that matters more when an early task has aggressive overrides like low warmup_iterations or min_iterations. If first-position bias is a concern, put a throwaway warm-up task first, or call run() twice and use the second result set.

type (): Promise<BenchmarkResult[]>

returns Promise<BenchmarkResult[]>

table

Format results as an ASCII table with percentiles, min/max, and relative performance.

type (options?: BenchmarkFormatTableOptions | undefined): string

options?

type BenchmarkFormatTableOptions | undefined
optional
returns string
// Standard table console.log(bench.table()); // Grouped by category console.log(bench.table({ groups: [ { name: 'FAST PATHS', filter: (r) => r.name.includes('fast') }, { name: 'SLOW PATHS', filter: (r) => r.name.includes('slow') }, ] }));

markdown

Format results as a Markdown table.

type (options?: BenchmarkFormatTableOptions | undefined): string

options?

formatting options (groups for organized output with optional baselines)

type BenchmarkFormatTableOptions | undefined
optional
returns string

formatted markdown string

// Standard table console.log(bench.markdown()); // Grouped by category with custom baseline console.log(bench.markdown({ groups: [ { name: 'Format', filter: (r) => r.name.startsWith('format/'), baseline: 'format/prettier' }, { name: 'Parse', filter: (r) => r.name.startsWith('parse/') }, ] }));

json

Format results as JSON.

type (options?: BenchmarkFormatJsonOptions | undefined): string

options?

formatting options (pretty, include_timings)

type BenchmarkFormatJsonOptions | undefined
optional
returns string

JSON string

results

Get the benchmark results.

type (): BenchmarkResult[]

returns BenchmarkResult[]

shallow copy of the results array (prevents external mutation)

results_by_name

Get results as a map for convenient lookup by task name.

type (): Map<string, BenchmarkResult>

returns Map<string, BenchmarkResult>

fresh Map of task name to benchmark result (prevents external mutation)

const results_map = bench.results_by_name(); const slugify_result = results_map.get('slugify'); if (slugify_result) { console.log(`slugify: ${slugify_result.stats.ops_per_second} ops/sec`); }

reset

Reset the benchmark results. Keeps tasks intact so benchmarks can be rerun.

type (): this

returns this

this Benchmark instance for chaining

clear

Clear everything (results and tasks).

type (): this

returns this

this Benchmark instance for chaining

summary

Get a quick text summary of the fastest task.

type (): string

returns string

human-readable summary string

console.log(bench.summary()); // "Fastest: slugify_v2 (1,285,515.00 ops/sec, 786.52ns per op)" // "Slowest: slugify (252,955.00 ops/sec, 3.95μs per op)" // "Speed difference: 5.08x"

has_results

Check if the benchmark has been run and has results.

type boolean

getter
if (bench.has_results) { console.log(bench.table()); }

benchmark_warmup
#

benchmark.ts view source

(fn: () => unknown, iterations: number, async_hint?: boolean | undefined): Promise<boolean> import {benchmark_warmup} from '@fuzdev/fuz_util/benchmark.js';

Warmup function by running it multiple times. Detects whether the function is async based on return value.

When no async_hint is provided, at least one detection iteration runs even if iterations is 0 — otherwise async detection would be impossible and async functions would have their returned promises leaked as unhandled.

fn

function to warmup (sync or async)

type () => unknown

iterations

type number

async_hint?

if provided, use this instead of detecting

type boolean | undefined
optional

returns

Promise<boolean>

whether the function is async

examples

const is_async = await benchmark_warmup(() => expensive_operation(), 10);

Depends on
#