initial commit
This commit is contained in:
177
benchmarks/result/collection.bench.ts
Normal file
177
benchmarks/result/collection.bench.ts
Normal file
@@ -0,0 +1,177 @@
|
||||
import { bench, describe } from 'vitest';
|
||||
import { STANDARD, EXTENDED } from '../helpers/bench-options.js';
|
||||
import { SIZES, errorIndices } from '../helpers/data-generators.js';
|
||||
import {
|
||||
ok,
|
||||
err,
|
||||
Result,
|
||||
ntOk,
|
||||
ntErr,
|
||||
NtResult,
|
||||
TsOk,
|
||||
TsErr,
|
||||
TsResult,
|
||||
OxOk,
|
||||
OxErr,
|
||||
E,
|
||||
pipe,
|
||||
TmResult,
|
||||
} from '../helpers/imports.js';
|
||||
import * as RA from 'fp-ts/ReadonlyArray';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Result.all — all Ok
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
for (const size of SIZES) {
|
||||
const opts = size >= 10_000 ? EXTENDED : STANDARD;
|
||||
|
||||
const nmAll = Array.from({ length: size }, (_, i) => ok(i));
|
||||
const ntAll = Array.from({ length: size }, (_, i) => ntOk(i));
|
||||
const tsAll = Array.from({ length: size }, (_, i) => TsOk<number, string>(i));
|
||||
const oxAll = Array.from({ length: size }, (_, i) => OxOk(i));
|
||||
const fpAll = Array.from({ length: size }, (_, i) => E.right(i));
|
||||
const tmAll = Array.from({ length: size }, (_, i) => TmResult.ok<number, string>(i));
|
||||
|
||||
describe(`Result.all — ${size} items, all Ok`, () => {
|
||||
bench('native-monad', () => { Result.all(nmAll); }, opts);
|
||||
bench('neverthrow', () => { NtResult.combine(ntAll); }, opts);
|
||||
bench('ts-results-es', () => { TsResult.all(...tsAll); }, opts);
|
||||
// oxide.ts: no built-in all/combine
|
||||
bench('fp-ts', () => { pipe(fpAll, RA.sequence(E.Applicative)); }, opts);
|
||||
// true-myth: no built-in all
|
||||
bench('true-myth (manual)', () => {
|
||||
const values: number[] = [];
|
||||
for (const r of tmAll) {
|
||||
if (TmResult.isErr(r)) return r;
|
||||
values.push((r as { value: number }).value);
|
||||
}
|
||||
return TmResult.ok(values);
|
||||
}, opts);
|
||||
});
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Result.all — 20% Err (short-circuit)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
for (const size of SIZES) {
|
||||
const opts = size >= 10_000 ? EXTENDED : STANDARD;
|
||||
const errIdx = errorIndices(size, 0.2);
|
||||
|
||||
const nmMixed = Array.from({ length: size }, (_, i) =>
|
||||
errIdx.has(i) ? err('fail') : ok(i),
|
||||
);
|
||||
const ntMixed = Array.from({ length: size }, (_, i) =>
|
||||
errIdx.has(i) ? ntErr('fail') : ntOk(i),
|
||||
);
|
||||
const tsMixed = Array.from({ length: size }, (_, i) =>
|
||||
errIdx.has(i) ? TsErr<number, string>('fail') : TsOk<number, string>(i),
|
||||
);
|
||||
const fpMixed = Array.from({ length: size }, (_, i) =>
|
||||
errIdx.has(i) ? E.left('fail' as const) : E.right(i),
|
||||
);
|
||||
const tmMixed = Array.from({ length: size }, (_, i) =>
|
||||
errIdx.has(i) ? TmResult.err<number, string>('fail') : TmResult.ok<number, string>(i),
|
||||
);
|
||||
|
||||
describe(`Result.all — ${size} items, 20% Err (short-circuit)`, () => {
|
||||
bench('native-monad', () => { Result.all(nmMixed); }, opts);
|
||||
bench('neverthrow', () => { NtResult.combine(ntMixed as any); }, opts);
|
||||
bench('ts-results-es', () => { TsResult.all(...tsMixed); }, opts);
|
||||
bench('fp-ts', () => { pipe(fpMixed, RA.sequence(E.Applicative)); }, opts);
|
||||
bench('true-myth (manual)', () => {
|
||||
const values: number[] = [];
|
||||
for (const r of tmMixed) {
|
||||
if (TmResult.isErr(r)) return r;
|
||||
values.push((r as { value: number }).value);
|
||||
}
|
||||
return TmResult.ok(values);
|
||||
}, opts);
|
||||
});
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Result.partition
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
for (const size of SIZES) {
|
||||
const opts = size >= 10_000 ? EXTENDED : STANDARD;
|
||||
const errIdx = errorIndices(size, 0.2);
|
||||
|
||||
const nmMixed = Array.from({ length: size }, (_, i) =>
|
||||
errIdx.has(i) ? err('fail') : ok(i),
|
||||
);
|
||||
const ntMixed = Array.from({ length: size }, (_, i) =>
|
||||
errIdx.has(i) ? ntErr('fail') : ntOk(i),
|
||||
);
|
||||
const fpMixed = Array.from({ length: size }, (_, i) =>
|
||||
errIdx.has(i) ? E.left('fail' as const) : E.right(i),
|
||||
);
|
||||
|
||||
describe(`Result.partition — ${size} items`, () => {
|
||||
bench('native-monad', () => { Result.partition(nmMixed); }, opts);
|
||||
bench('neverthrow (manual)', () => {
|
||||
const values: number[] = [];
|
||||
const errors: string[] = [];
|
||||
for (const r of ntMixed) {
|
||||
if (r.isOk()) values.push(r.value);
|
||||
else errors.push(r.error);
|
||||
}
|
||||
return { values, errors };
|
||||
}, opts);
|
||||
bench('fp-ts', () => { RA.separate(fpMixed); }, opts);
|
||||
});
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Result.compact
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
for (const size of SIZES) {
|
||||
const opts = size >= 10_000 ? EXTENDED : STANDARD;
|
||||
const errIdx = errorIndices(size, 0.2);
|
||||
|
||||
const nmMixed = Array.from({ length: size }, (_, i) =>
|
||||
errIdx.has(i) ? err('fail') : ok(i),
|
||||
);
|
||||
const ntMixed = Array.from({ length: size }, (_, i) =>
|
||||
errIdx.has(i) ? ntErr('fail') : ntOk(i),
|
||||
);
|
||||
|
||||
describe(`Result.compact — ${size} items`, () => {
|
||||
bench('native-monad', () => { Result.compact(nmMixed); }, opts);
|
||||
bench('neverthrow (manual)', () => {
|
||||
const values: number[] = [];
|
||||
for (const r of ntMixed) {
|
||||
if (r.isOk()) values.push(r.value);
|
||||
}
|
||||
return values;
|
||||
}, opts);
|
||||
});
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Result.some / Result.every
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
for (const size of [100, 1_000]) {
|
||||
const errIdx = errorIndices(size, 0.2);
|
||||
|
||||
const nmMixed = Array.from({ length: size }, (_, i) =>
|
||||
errIdx.has(i) ? err('fail') : ok(i),
|
||||
);
|
||||
const ntMixed = Array.from({ length: size }, (_, i) =>
|
||||
errIdx.has(i) ? ntErr('fail') : ntOk(i),
|
||||
);
|
||||
|
||||
describe(`Result.some — ${size} items`, () => {
|
||||
bench('native-monad', () => { Result.some(nmMixed); }, STANDARD);
|
||||
bench('neverthrow (manual)', () => { ntMixed.some(r => r.isOk()); }, STANDARD);
|
||||
});
|
||||
|
||||
describe(`Result.every — ${size} items`, () => {
|
||||
bench('native-monad', () => { Result.every(nmMixed); }, STANDARD);
|
||||
bench('neverthrow (manual)', () => { ntMixed.every(r => r.isOk()); }, STANDARD);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user