initial commit
This commit is contained in:
128
benchmarks/query/chaining.bench.ts
Normal file
128
benchmarks/query/chaining.bench.ts
Normal file
@@ -0,0 +1,128 @@
|
||||
import { bench, describe } from 'vitest';
|
||||
import { STANDARD } from '../helpers/bench-options.js';
|
||||
import {
|
||||
okSome,
|
||||
okNone,
|
||||
errNone,
|
||||
E,
|
||||
O,
|
||||
pipe,
|
||||
} from '../helpers/imports.js';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 5-step pipeline — OkSome path
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe('Query chaining — 5-step pipeline (all OkSome)', () => {
|
||||
bench('native-monad', () => {
|
||||
okSome(42)
|
||||
.map(x => x * 2)
|
||||
.flatMap(x => (x > 0 ? okSome(x) : okNone()))
|
||||
.map(x => ({ value: x }))
|
||||
.flatMap(x => okSome({ ...x, label: 'result' }))
|
||||
.map(x => JSON.stringify(x));
|
||||
}, STANDARD);
|
||||
|
||||
bench('fp-ts (nested)', () => {
|
||||
pipe(
|
||||
E.right(O.some(42)) as E.Either<string, O.Option<number>>,
|
||||
E.map(O.map(x => x * 2)),
|
||||
E.flatMap(inner =>
|
||||
pipe(
|
||||
inner,
|
||||
O.match(
|
||||
() => E.right(O.none) as E.Either<string, O.Option<number>>,
|
||||
v => (v > 0 ? E.right(O.some(v)) : E.right(O.none)) as E.Either<string, O.Option<number>>,
|
||||
),
|
||||
),
|
||||
),
|
||||
E.map(O.map(x => ({ value: x }))),
|
||||
E.flatMap(inner =>
|
||||
pipe(
|
||||
inner,
|
||||
O.match(
|
||||
() => E.right(O.none) as E.Either<string, O.Option<{ value: number; label: string }>>,
|
||||
v => E.right(O.some({ ...v, label: 'result' })),
|
||||
),
|
||||
),
|
||||
),
|
||||
E.map(O.map(x => JSON.stringify(x))),
|
||||
);
|
||||
}, STANDARD);
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ErrNone short-circuit — 9 no-op maps
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe('Query chaining — ErrNone at step 1, 9 no-op maps', () => {
|
||||
const nm = errNone('fail');
|
||||
const fp = E.left('fail') as E.Either<string, O.Option<number>>;
|
||||
const fn = (x: number) => x + 1;
|
||||
|
||||
bench('native-monad', () => {
|
||||
nm.map(fn).map(fn).map(fn).map(fn).map(fn).map(fn).map(fn).map(fn).map(fn);
|
||||
}, STANDARD);
|
||||
|
||||
bench('fp-ts (nested)', () => {
|
||||
pipe(
|
||||
fp,
|
||||
E.map(O.map(fn)),
|
||||
E.map(O.map(fn)),
|
||||
E.map(O.map(fn)),
|
||||
E.map(O.map(fn)),
|
||||
E.map(O.map(fn)),
|
||||
E.map(O.map(fn)),
|
||||
E.map(O.map(fn)),
|
||||
E.map(O.map(fn)),
|
||||
E.map(O.map(fn)),
|
||||
);
|
||||
}, STANDARD);
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// OkNone short-circuit — 9 no-op maps
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe('Query chaining — OkNone, 9 no-op maps', () => {
|
||||
const nm = okNone();
|
||||
const fp = E.right(O.none) as E.Either<string, O.Option<number>>;
|
||||
const fn = (x: number) => x + 1;
|
||||
|
||||
bench('native-monad', () => {
|
||||
nm.map(fn).map(fn).map(fn).map(fn).map(fn).map(fn).map(fn).map(fn).map(fn);
|
||||
}, STANDARD);
|
||||
|
||||
bench('fp-ts (nested)', () => {
|
||||
pipe(
|
||||
fp,
|
||||
E.map(O.map(fn)),
|
||||
E.map(O.map(fn)),
|
||||
E.map(O.map(fn)),
|
||||
E.map(O.map(fn)),
|
||||
E.map(O.map(fn)),
|
||||
E.map(O.map(fn)),
|
||||
E.map(O.map(fn)),
|
||||
E.map(O.map(fn)),
|
||||
E.map(O.map(fn)),
|
||||
);
|
||||
}, STANDARD);
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 20-step deep map chain — OkSome path
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe('Query chaining — 20 maps on OkSome', () => {
|
||||
const fn = (x: number) => x + 1;
|
||||
|
||||
bench('native-monad', () => {
|
||||
let r = okSome(0);
|
||||
for (let i = 0; i < 20; i++) r = r.map(fn);
|
||||
}, STANDARD);
|
||||
|
||||
bench('fp-ts (nested)', () => {
|
||||
let r = E.right(O.some(0)) as E.Either<string, O.Option<number>>;
|
||||
for (let i = 0; i < 20; i++) r = pipe(r, E.map(O.map(fn)));
|
||||
}, STANDARD);
|
||||
});
|
||||
Reference in New Issue
Block a user