This repository has been archived by the owner on Jan 6, 2025. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
move missing keys checks to improve perfs (#224)
- Loading branch information
Showing
8 changed files
with
194 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@effect/schema": patch | ||
--- | ||
|
||
move missing keys checks to improve perfs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
import * as D from "@effect/data/Debug" | ||
import type { ParseOptions } from "@effect/schema/AST" | ||
import * as P from "@effect/schema/Parser" | ||
import * as t from "@effect/schema/Schema" | ||
import * as Benchmark from "benchmark" | ||
import { z } from "zod" | ||
|
||
D.runtimeDebug.tracingEnabled = true | ||
|
||
/* | ||
parseEither (good) x 276,758 ops/sec ±0.56% (89 runs sampled) | ||
zod (good) x 32,104 ops/sec ±6.04% (81 runs sampled) | ||
parseEither (bad) x 805,793 ops/sec ±6.90% (81 runs sampled) | ||
zod (bad) x 9,543 ops/sec ±4.28% (81 runs sampled) | ||
*/ | ||
|
||
const suite = new Benchmark.Suite() | ||
|
||
const Vector = t.tuple(t.number, t.number, t.number) | ||
const VectorZod = z.tuple([z.number(), z.number(), z.number()]) | ||
|
||
const Asteroid = t.struct({ | ||
type: t.literal("asteroid"), | ||
location: Vector, | ||
mass: t.number | ||
}) | ||
const AsteroidZod = z.object({ | ||
type: z.literal("asteroid"), | ||
location: VectorZod, | ||
mass: z.number() | ||
}) | ||
|
||
const Planet = t.struct({ | ||
type: t.literal("planet"), | ||
location: Vector, | ||
mass: t.number, | ||
population: t.number, | ||
habitable: t.boolean | ||
}) | ||
const PlanetZod = z.object({ | ||
type: z.literal("planet"), | ||
location: VectorZod, | ||
mass: z.number(), | ||
population: z.number(), | ||
habitable: z.boolean() | ||
}) | ||
|
||
const Rank = t.union( | ||
t.literal("captain"), | ||
t.literal("first mate"), | ||
t.literal("officer"), | ||
t.literal("ensign") | ||
) | ||
const RankZod = z.union([ | ||
z.literal("captain"), | ||
z.literal("first mate"), | ||
z.literal("officer"), | ||
z.literal("ensign") | ||
]) | ||
|
||
const CrewMember = t.struct({ | ||
name: t.string, | ||
age: t.number, | ||
rank: Rank, | ||
home: Planet | ||
}) | ||
const CrewMemberZod = z.object({ | ||
name: z.string(), | ||
age: z.number(), | ||
rank: RankZod, | ||
home: PlanetZod | ||
}) | ||
|
||
const Ship = t.struct({ | ||
type: t.literal("ship"), | ||
location: Vector, | ||
mass: t.number, | ||
name: t.string, | ||
crew: t.array(CrewMember) | ||
}) | ||
const ShipZod = z.object({ | ||
type: z.literal("ship"), | ||
location: VectorZod, | ||
mass: z.number(), | ||
name: z.string(), | ||
crew: z.array(CrewMemberZod) | ||
}) | ||
|
||
export const schema = t.union(Asteroid, Planet, Ship) | ||
export const schemaZod = z.union([AsteroidZod, PlanetZod, ShipZod]) // unfair: no discriminated union | ||
|
||
export const parseEither = P.parseEither(schema) | ||
const options: ParseOptions = { errors: "first" } // unfair: "first" instead of "all" | ||
|
||
const good = { | ||
type: "ship", | ||
location: [1, 2, 3], | ||
mass: 4, | ||
name: "foo", | ||
crew: [ | ||
{ | ||
name: "bar", | ||
age: 44, | ||
rank: "captain", | ||
home: { | ||
type: "planet", | ||
location: [5, 6, 7], | ||
mass: 8, | ||
population: 1000, | ||
habitable: true | ||
} | ||
} | ||
] | ||
} | ||
|
||
const bad = { | ||
type: "ship", | ||
location: [1, 2, "a"], | ||
mass: 4, | ||
name: "foo", | ||
crew: [ | ||
{ | ||
name: "bar", | ||
age: 44, | ||
rank: "captain", | ||
home: { | ||
type: "planet", | ||
location: [5, 6, 7], | ||
mass: 8, | ||
population: 1000, | ||
habitable: "true" // unfair: take advantage of /schema's "sort fields by weight" internal feature | ||
} | ||
} | ||
] | ||
} | ||
|
||
suite | ||
.add("parseEither (good)", function() { | ||
parseEither(good, options) | ||
}) | ||
.add("zod (good)", function() { | ||
schemaZod.safeParse(good) | ||
}) | ||
.add("parseEither (bad)", function() { | ||
parseEither(bad, options) | ||
}) | ||
.add("zod (bad)", function() { | ||
schemaZod.safeParse(bad) | ||
}) | ||
.on("cycle", function(event: any) { | ||
console.log(String(event.target)) | ||
}) | ||
.on("complete", function(this: any) { | ||
console.log("Fastest is " + this.filter("fastest").map("name")) | ||
}) | ||
.run({ async: true }) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters