3.3 KiB
3.3 KiB
native-monad benchmarks
Comprehensive benchmark suite comparing native-monad against popular TypeScript monad libraries.
Competitor Libraries
| Library | Result type | Option type | Async |
|---|---|---|---|
| neverthrow | Result<T,E> |
— | ResultAsync |
| ts-results-es | Result<T,E> |
Option<T> |
— |
| oxide.ts | Result<T,E> |
Option<T> |
— |
| fp-ts | Either<E,A> |
Option<A> |
TaskEither |
| true-myth | Result<T,E> |
Maybe<T> |
— |
Prerequisites
The parent project must be built before running benchmarks:
cd .. && pnpm build
This happens automatically via the prebench script when running pnpm bench.
Running Benchmarks
# Install dependencies (first time only)
pnpm install
# Run all benchmarks
pnpm bench
# Run by type
pnpm bench:result
pnpm bench:option
pnpm bench:query
pnpm bench:scenarios
# Run a single file
npx vitest bench result/construction.bench.ts --run
Reading Output
Vitest bench outputs a table per describe group:
| Column | Meaning |
|---|---|
hz |
Operations per second |
min |
Fastest single iteration (ms) |
max |
Slowest single iteration (ms) |
mean |
Average iteration time (ms) |
p75 |
75th percentile iteration time (ms) |
p99 |
99th percentile iteration time (ms) |
rme |
Relative margin of error (%) |
After all groups, a Summary section shows the fastest library per group and relative slowdown factors.
Benchmark Structure
result/ — Result/Either type benchmarks
option/ — Option/Maybe type benchmarks
query/ — Query (three-state) benchmarks + nested equivalents
scenarios/ — Real-world patterns (parsing, validation, error propagation)
helpers/ — Shared config, data generators, imports
Each benchmark file covers a specific operation category:
construction.bench.ts— Creating Ok/Err/Some/None instancesinstance-methods.bench.ts— map, flatMap, mapErr, match, filtertype-guards.bench.ts— isOk/isErr/isSome/isNoneconversion.bench.ts— toNullable, toUndefined, toStringcollection.bench.ts— all, partition, compact, some, everychaining.bench.ts— Multi-step pipelinesfrom-wrapping.bench.ts— Try-catch wrappingasync.bench.ts— Promise-based operations
Caveats
- Microbenchmarks measure isolated operations. Real-world performance depends on usage patterns, GC pressure, and JIT behavior in context.
- Async benchmarks have higher variance due to event loop scheduling. Results use extended warmup/time to compensate.
- fp-ts uses a fundamentally different paradigm (
pipe+ standalone functions vs class methods). The benchmarks use each library's idiomatic API for fair comparison. bench.skipappears when a library lacks an equivalent operation — no fabricated workarounds.- Collection benchmarks test at sizes 100 and 10K to show scaling behavior.