-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Expand file tree
/
Copy pathobject-maybe-async.ts
More file actions
83 lines (80 loc) · 2.51 KB
/
object-maybe-async.ts
File metadata and controls
83 lines (80 loc) · 2.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import * as z from "../zod/src/v4/index.js";
import { makeData } from "./benchUtil.js";
import { metabench } from "./metabench.js";
// 1. small flat object — purely sync, exercises ZodObject fastpass directly.
{
const schema = z.object({
string: z.string(),
boolean: z.boolean(),
number: z.number(),
});
const DATA = makeData(1000, () => ({
number: Math.random(),
string: `${Math.random()}`,
boolean: Math.random() > 0.5,
}));
const bench = metabench("flat sync object — safeParse vs safeParseMaybeAsync", {
safeParse() {
for (const _ of DATA) schema.safeParse(_);
},
safeParseMaybeAsync() {
for (const _ of DATA) schema.safeParseMaybeAsync(_);
},
});
await bench.run();
}
// 2. nested + discriminated union — sync but non-trivial; proves the
// fastpass engages end-to-end down the schema tree.
{
const inner = z.object({ tag: z.string(), score: z.number() });
const schema = z.object({
id: z.string(),
nested: z.object({ a: z.string(), b: z.number(), c: z.boolean() }),
items: z.array(inner),
kind: z.discriminatedUnion("type", [
z.object({ type: z.literal("a"), x: z.string() }),
z.object({ type: z.literal("b"), y: z.number() }),
]),
});
const DATA = makeData(500, () => ({
id: `${Math.random()}`,
nested: { a: "x", b: 1, c: true },
items: [
{ tag: "p", score: 1 },
{ tag: "q", score: 2 },
],
kind: Math.random() > 0.5 ? { type: "a", x: "ok" } : { type: "b", y: 1 },
}));
const bench = metabench("nested + discriminated sync — safeParse vs safeParseMaybeAsync", {
safeParse() {
for (const _ of DATA) schema.safeParse(_);
},
safeParseMaybeAsync() {
for (const _ of DATA) schema.safeParseMaybeAsync(_);
},
});
await bench.run();
}
// 3. mostly-sync schema with one deep async refine — quantifies the
// double-walk cost on the async fallback path vs safeParseAsync.
{
const schema = z.object({
id: z.string(),
nested: z.object({ a: z.string(), b: z.number() }),
tail: z.string().refine(async (s) => s.length >= 0),
});
const DATA = makeData(200, () => ({
id: `${Math.random()}`,
nested: { a: "x", b: 1 },
tail: "y",
}));
const bench = metabench("mostly-sync + 1 async refine — safeParseAsync vs safeParseMaybeAsync", {
async safeParseAsync() {
for (const _ of DATA) await schema.safeParseAsync(_);
},
async safeParseMaybeAsync() {
for (const _ of DATA) await schema.safeParseMaybeAsync(_);
},
});
await bench.run();
}