initial commit
This commit is contained in:
127
benchmarks/scenarios/parsing.bench.ts
Normal file
127
benchmarks/scenarios/parsing.bench.ts
Normal file
@@ -0,0 +1,127 @@
|
||||
import { bench, describe } from 'vitest';
|
||||
import { STANDARD } from '../helpers/bench-options.js';
|
||||
import {
|
||||
ok,
|
||||
err,
|
||||
Result,
|
||||
ntOk,
|
||||
ntErr,
|
||||
ntFromThrowable,
|
||||
TsOk,
|
||||
TsErr,
|
||||
OxOk,
|
||||
OxErr,
|
||||
E,
|
||||
pipe,
|
||||
TmResult,
|
||||
} from '../helpers/imports.js';
|
||||
|
||||
const validJson = '{"name":"Alice","age":30,"email":"alice@example.com"}';
|
||||
const invalidJson = 'not json {{{';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// JSON parsing — valid input
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe('Scenario: JSON parse + extract field — valid input', () => {
|
||||
bench('native-monad', () => {
|
||||
Result.from(() => JSON.parse(validJson), () => 'parse error')
|
||||
.map(obj => obj.name as string)
|
||||
.flatMap(name => (name.length > 0 ? ok(name) : err('empty name')));
|
||||
}, STANDARD);
|
||||
|
||||
bench('neverthrow', () => {
|
||||
ntFromThrowable(() => JSON.parse(validJson), () => 'parse error')()
|
||||
.map(obj => obj.name as string)
|
||||
.andThen(name => (name.length > 0 ? ntOk(name) : ntErr('empty name')));
|
||||
}, STANDARD);
|
||||
|
||||
bench('ts-results-es', () => {
|
||||
let r;
|
||||
try { r = TsOk(JSON.parse(validJson)); }
|
||||
catch { r = TsErr('parse error'); }
|
||||
r.map((obj: any) => obj.name as string)
|
||||
.andThen((name: string) => (name.length > 0 ? TsOk(name) : TsErr('empty name')));
|
||||
}, STANDARD);
|
||||
|
||||
bench('oxide.ts', () => {
|
||||
let r;
|
||||
try { r = OxOk(JSON.parse(validJson)); }
|
||||
catch { r = OxErr('parse error'); }
|
||||
r.map((obj: any) => obj.name as string)
|
||||
.andThen((name: string) => (name.length > 0 ? OxOk(name) : OxErr('parse error')));
|
||||
}, STANDARD);
|
||||
|
||||
bench('fp-ts', () => {
|
||||
pipe(
|
||||
E.tryCatch(() => JSON.parse(validJson), () => 'parse error'),
|
||||
E.map(obj => obj.name as string),
|
||||
E.flatMap(name => (name.length > 0 ? E.right(name) : E.left('empty name'))),
|
||||
);
|
||||
}, STANDARD);
|
||||
|
||||
bench('true-myth', () => {
|
||||
TmResult.tryOr('parse error', () => JSON.parse(validJson))
|
||||
.map(obj => obj.name as string)
|
||||
.andThen(name => (name.length > 0 ? TmResult.ok(name) : TmResult.err('empty name')));
|
||||
}, STANDARD);
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// JSON parsing — invalid input
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe('Scenario: JSON parse + extract field — invalid input', () => {
|
||||
bench('native-monad', () => {
|
||||
Result.from(() => JSON.parse(invalidJson), () => 'parse error')
|
||||
.map(obj => obj.name as string)
|
||||
.flatMap(name => (name.length > 0 ? ok(name) : err('empty name')));
|
||||
}, STANDARD);
|
||||
|
||||
bench('neverthrow', () => {
|
||||
ntFromThrowable(() => JSON.parse(invalidJson), () => 'parse error')()
|
||||
.map(obj => obj.name as string)
|
||||
.andThen(name => (name.length > 0 ? ntOk(name) : ntErr('empty name')));
|
||||
}, STANDARD);
|
||||
|
||||
bench('fp-ts', () => {
|
||||
pipe(
|
||||
E.tryCatch(() => JSON.parse(invalidJson), () => 'parse error'),
|
||||
E.map(obj => obj.name as string),
|
||||
E.flatMap(name => (name.length > 0 ? E.right(name) : E.left('empty name'))),
|
||||
);
|
||||
}, STANDARD);
|
||||
|
||||
bench('true-myth', () => {
|
||||
TmResult.tryOr('parse error', () => JSON.parse(invalidJson))
|
||||
.map(obj => obj.name as string)
|
||||
.andThen(name => (name.length > 0 ? TmResult.ok(name) : TmResult.err('empty name')));
|
||||
}, STANDARD);
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Number parsing — valid
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe('Scenario: number parsing — valid', () => {
|
||||
const input = '42.5';
|
||||
|
||||
bench('native-monad', () => {
|
||||
Result.from(() => {
|
||||
const n = Number(input);
|
||||
if (Number.isNaN(n)) throw new Error('NaN');
|
||||
return n;
|
||||
}).flatMap(n => (n > 0 ? ok(n) : err('not positive')));
|
||||
}, STANDARD);
|
||||
|
||||
bench('fp-ts', () => {
|
||||
pipe(
|
||||
E.tryCatch(() => {
|
||||
const n = Number(input);
|
||||
if (Number.isNaN(n)) throw new Error('NaN');
|
||||
return n;
|
||||
}, () => 'parse error'),
|
||||
E.flatMap(n => (n > 0 ? E.right(n) : E.left('not positive'))),
|
||||
);
|
||||
}, STANDARD);
|
||||
});
|
||||
Reference in New Issue
Block a user