Files
native-monad/benchmarks/scenarios/error-propagation.bench.ts
2026-03-30 08:34:35 +02:00

146 lines
3.8 KiB
TypeScript

import { bench, describe } from 'vitest';
import { STANDARD } from '../helpers/bench-options.js';
import {
ok,
err,
none,
ntOk,
ntErr,
TsOk,
TsErr,
TsNone,
OxOk,
OxErr,
OxNone,
E,
O,
pipe,
TmResult,
TmMaybe,
} from '../helpers/imports.js';
const fn = (x: number) => x + 1;
// ---------------------------------------------------------------------------
// Error propagation through 20 map calls
// ---------------------------------------------------------------------------
describe('Scenario: Err through 20 map calls', () => {
const nm = err('fail');
const nt = ntErr('fail');
const ts = TsErr<number, string>('fail');
const ox = OxErr('fail');
const fp = E.left('fail') as E.Either<string, number>;
const tm = TmResult.err<number, string>('fail');
bench('native-monad', () => {
let r = nm as any;
for (let i = 0; i < 20; i++) r = r.map(fn);
}, STANDARD);
bench('neverthrow', () => {
let r = nt as any;
for (let i = 0; i < 20; i++) r = r.map(fn);
}, STANDARD);
bench('ts-results-es', () => {
let r = ts as any;
for (let i = 0; i < 20; i++) r = r.map(fn);
}, STANDARD);
bench('oxide.ts', () => {
let r = ox as any;
for (let i = 0; i < 20; i++) r = r.map(fn);
}, STANDARD);
bench('fp-ts', () => {
let r = fp;
for (let i = 0; i < 20; i++) r = pipe(r, E.map(fn));
}, STANDARD);
bench('true-myth', () => {
let r = tm as any;
for (let i = 0; i < 20; i++) r = r.map(fn);
}, STANDARD);
});
// ---------------------------------------------------------------------------
// Error propagation through 20 flatMap calls
// ---------------------------------------------------------------------------
describe('Scenario: Err through 20 flatMap calls', () => {
const nm = err('fail');
const nt = ntErr('fail');
const ts = TsErr<number, string>('fail');
const ox = OxErr('fail');
const fp = E.left('fail') as E.Either<string, number>;
const tm = TmResult.err<number, string>('fail');
bench('native-monad', () => {
let r = nm as any;
for (let i = 0; i < 20; i++) r = r.flatMap((x: number) => ok(x + 1));
}, STANDARD);
bench('neverthrow', () => {
let r = nt as any;
for (let i = 0; i < 20; i++) r = r.andThen((x: number) => ntOk(x + 1));
}, STANDARD);
bench('ts-results-es', () => {
let r = ts as any;
for (let i = 0; i < 20; i++) r = r.andThen((x: number) => TsOk(x + 1));
}, STANDARD);
bench('oxide.ts', () => {
let r = ox as any;
for (let i = 0; i < 20; i++) r = r.andThen((x: number) => OxOk(x + 1));
}, STANDARD);
bench('fp-ts', () => {
let r = fp;
for (let i = 0; i < 20; i++) r = pipe(r, E.flatMap(x => E.right(x + 1)));
}, STANDARD);
bench('true-myth', () => {
let r = tm as any;
for (let i = 0; i < 20; i++) r = r.andThen((x: number) => TmResult.ok(x + 1));
}, STANDARD);
});
// ---------------------------------------------------------------------------
// None propagation through 20 map calls (Option)
// ---------------------------------------------------------------------------
describe('Scenario: None through 20 map calls', () => {
const nm = none();
const ts = TsNone;
const ox = OxNone;
const fp = O.none as O.Option<number>;
const tm = TmMaybe.nothing<number>();
bench('native-monad', () => {
let r = nm as any;
for (let i = 0; i < 20; i++) r = r.map(fn);
}, STANDARD);
bench('ts-results-es', () => {
let r = ts as any;
for (let i = 0; i < 20; i++) r = r.map(fn);
}, STANDARD);
bench('oxide.ts', () => {
let r = ox as any;
for (let i = 0; i < 20; i++) r = r.map(fn);
}, STANDARD);
bench('fp-ts', () => {
let r = fp;
for (let i = 0; i < 20; i++) r = pipe(r, O.map(fn));
}, STANDARD);
bench('true-myth', () => {
let r = tm as any;
for (let i = 0; i < 20; i++) r = r.map(fn);
}, STANDARD);
});