initial commit
This commit is contained in:
144
benchmarks/query/collection.bench.ts
Normal file
144
benchmarks/query/collection.bench.ts
Normal file
@@ -0,0 +1,144 @@
|
||||
import { bench, describe } from 'vitest';
|
||||
import { STANDARD, EXTENDED } from '../helpers/bench-options.js';
|
||||
import { SIZES, errorIndices } from '../helpers/data-generators.js';
|
||||
import {
|
||||
okSome,
|
||||
okNone,
|
||||
errNone,
|
||||
Query,
|
||||
E,
|
||||
O,
|
||||
pipe,
|
||||
} from '../helpers/imports.js';
|
||||
import * as RA from 'fp-ts/ReadonlyArray';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Query.all — all OkSome
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
for (const size of SIZES) {
|
||||
const opts = size >= 10_000 ? EXTENDED : STANDARD;
|
||||
|
||||
const nmAll = Array.from({ length: size }, (_, i) => okSome(i));
|
||||
const fpAll = Array.from({ length: size }, (_, i) =>
|
||||
E.right(O.some(i)) as E.Either<string, O.Option<number>>,
|
||||
);
|
||||
|
||||
describe(`Query.all — ${size} items, all OkSome`, () => {
|
||||
bench('native-monad', () => { Query.all(nmAll); }, opts);
|
||||
bench('fp-ts (nested, manual)', () => {
|
||||
const values: number[] = [];
|
||||
for (const item of fpAll) {
|
||||
if (E.isLeft(item)) return item;
|
||||
if (O.isNone(item.right)) continue;
|
||||
values.push(item.right.value);
|
||||
}
|
||||
return E.right(O.some(values));
|
||||
}, opts);
|
||||
});
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Query.all — mixed (OkSome + OkNone + ErrNone)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
for (const size of SIZES) {
|
||||
const opts = size >= 10_000 ? EXTENDED : STANDARD;
|
||||
const errIdx = errorIndices(size, 0.1);
|
||||
const noneIdx = errorIndices(size, 0.15);
|
||||
|
||||
const nmMixed = Array.from({ length: size }, (_, i) => {
|
||||
if (errIdx.has(i)) return errNone('fail');
|
||||
if (noneIdx.has(i)) return okNone();
|
||||
return okSome(i);
|
||||
});
|
||||
|
||||
const fpMixed = Array.from({ length: size }, (_, i) => {
|
||||
if (errIdx.has(i)) return E.left('fail') as E.Either<string, O.Option<number>>;
|
||||
if (noneIdx.has(i)) return E.right(O.none) as E.Either<string, O.Option<number>>;
|
||||
return E.right(O.some(i)) as E.Either<string, O.Option<number>>;
|
||||
});
|
||||
|
||||
describe(`Query.all — ${size} items, mixed (short-circuit)`, () => {
|
||||
bench('native-monad', () => { Query.all(nmMixed); }, opts);
|
||||
bench('fp-ts (nested, manual)', () => {
|
||||
const values: number[] = [];
|
||||
for (const item of fpMixed) {
|
||||
if (E.isLeft(item)) return item;
|
||||
if (O.isNone(item.right)) continue;
|
||||
values.push(item.right.value);
|
||||
}
|
||||
return E.right(O.some(values));
|
||||
}, opts);
|
||||
});
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Query.partition
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
for (const size of SIZES) {
|
||||
const opts = size >= 10_000 ? EXTENDED : STANDARD;
|
||||
const errIdx = errorIndices(size, 0.1);
|
||||
const noneIdx = errorIndices(size, 0.15);
|
||||
|
||||
const nmMixed = Array.from({ length: size }, (_, i) => {
|
||||
if (errIdx.has(i)) return errNone('fail');
|
||||
if (noneIdx.has(i)) return okNone();
|
||||
return okSome(i);
|
||||
});
|
||||
|
||||
const fpMixed = Array.from({ length: size }, (_, i) => {
|
||||
if (errIdx.has(i)) return E.left('fail') as E.Either<string, O.Option<number>>;
|
||||
if (noneIdx.has(i)) return E.right(O.none) as E.Either<string, O.Option<number>>;
|
||||
return E.right(O.some(i)) as E.Either<string, O.Option<number>>;
|
||||
});
|
||||
|
||||
describe(`Query.partition — ${size} items`, () => {
|
||||
bench('native-monad', () => { Query.partition(nmMixed); }, opts);
|
||||
bench('fp-ts (nested, manual)', () => {
|
||||
const values: number[] = [];
|
||||
const errors: string[] = [];
|
||||
let noneCount = 0;
|
||||
for (const item of fpMixed) {
|
||||
if (E.isLeft(item)) { errors.push(item.left); continue; }
|
||||
if (O.isNone(item.right)) { noneCount++; continue; }
|
||||
values.push(item.right.value);
|
||||
}
|
||||
return { values, noneCount, errors };
|
||||
}, opts);
|
||||
});
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Query.compact
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
for (const size of SIZES) {
|
||||
const opts = size >= 10_000 ? EXTENDED : STANDARD;
|
||||
const errIdx = errorIndices(size, 0.1);
|
||||
const noneIdx = errorIndices(size, 0.15);
|
||||
|
||||
const nmMixed = Array.from({ length: size }, (_, i) => {
|
||||
if (errIdx.has(i)) return errNone('fail');
|
||||
if (noneIdx.has(i)) return okNone();
|
||||
return okSome(i);
|
||||
});
|
||||
|
||||
const fpMixed = Array.from({ length: size }, (_, i) => {
|
||||
if (errIdx.has(i)) return E.left('fail') as E.Either<string, O.Option<number>>;
|
||||
if (noneIdx.has(i)) return E.right(O.none) as E.Either<string, O.Option<number>>;
|
||||
return E.right(O.some(i)) as E.Either<string, O.Option<number>>;
|
||||
});
|
||||
|
||||
describe(`Query.compact — ${size} items`, () => {
|
||||
bench('native-monad', () => { Query.compact(nmMixed); }, opts);
|
||||
bench('fp-ts (nested, manual)', () => {
|
||||
const values: number[] = [];
|
||||
for (const item of fpMixed) {
|
||||
if (E.isRight(item) && O.isSome(item.right)) values.push(item.right.value);
|
||||
}
|
||||
return values;
|
||||
}, opts);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user