From 15c18bacb0153bcff35faea0b893f939f99bf263 Mon Sep 17 00:00:00 2001 From: Luke Edwards Date: Tue, 6 Aug 2024 07:16:20 -0700 Subject: [PATCH] chore: add builders benchmark --- deno.lock | 5 ++++ readme.md | 17 ++++++++++++ scripts/bench.ts | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+) create mode 100644 scripts/bench.ts diff --git a/deno.lock b/deno.lock index 0653ece..15e0069 100644 --- a/deno.lock +++ b/deno.lock @@ -7,6 +7,7 @@ "jsr:@std/internal@^1.0.1": "jsr:@std/internal@1.0.1", "jsr:@std/path@^1.0": "jsr:@std/path@1.0.2", "jsr:@std/testing": "jsr:@std/testing@0.225.3", + "npm:@sinclair/typebox": "npm:@sinclair/typebox@0.32.35", "npm:oxc-transform@^0.23": "npm:oxc-transform@0.23.0" }, "jsr": { @@ -59,6 +60,10 @@ "integrity": "sha512-lkUSMK4fpUzbQ1RV2kBOSlQ2QItEbHWGzRMwUgBgWS3IyupzorOKY6G1YVQ9VvwkGDw+G/7LADRc3Yvs4Z5xFg==", "dependencies": {} }, + "@sinclair/typebox@0.32.35": { + "integrity": "sha512-Ul3YyOTU++to8cgNkttakC0dWvpERr6RYoHO2W47DLbFvrwBDJUY31B1sImH6JZSYc4Kt4PyHtoPNu+vL2r2dA==", + "dependencies": {} + }, "oxc-transform@0.23.0": { "integrity": "sha512-0wnyvQxUpz4/HQb26NMiX+JKTPZrBAPGMUBri8oRw2M35K6AwOiVyTekwlMkymR9NbXJcLo9N656a+L52LksVQ==", "dependencies": { diff --git a/readme.md b/readme.md index 94ed20c..876404f 100644 --- a/readme.md +++ b/readme.md @@ -119,6 +119,23 @@ always kept up-to-date. > **Note:** The API is the same across all JavaScript runtimes, regardless of [installation](#install) source. Only the package's name changes. +## Benchmarks + +> Run on Deno 1.45.5 `(release, aarch64-apple-darwin)` with v8 `12.7.224.13` + +``` +file: tschema/scripts/bench.ts +runtime: deno 1.45.5 (aarch64-apple-darwin) + +# Builders + tschema 5,273,942.5 iter/sec 189.61 ns/iter + sinclair/typebox 130,548.3 iter/sec 7.66 µs/iter + +# Summary + tschema + 40.4x faster than sinclair/typebox +``` + ## License MIT © [Luke Edwards](https://lukeed.com) diff --git a/scripts/bench.ts b/scripts/bench.ts new file mode 100644 index 0000000..a3016f7 --- /dev/null +++ b/scripts/bench.ts @@ -0,0 +1,71 @@ +import * as t from '../mod.ts'; +import { Type } from 'npm:@sinclair/typebox'; + +Deno.bench('tschema', { group: 'builder' }, () => { + let _ = t.object({ + uid: t.integer(), + name: t.string({ + description: 'full name', + examples: ['Alex Johnson'], + }), + isActive: t.boolean(), + avatar: t.optional( + t.string({ format: 'uri' }), + ), + achievements: t.tuple([ + t.number({ minimum: 0 }), // points + t.enum(['novice', 'pro', 'expert', 'master']), + ]), + interests: t.array( + t.string({ + minLength: 4, + maxLength: 36, + }), + ), + last_updated: t.integer({ + minimum: 0, + examples: [1722642982], + description: 'unix seconds', + }), + }); +}); + +Deno.bench('sinclair/typebox', { group: 'builder' }, () => { + let _ = Type.Object({ + uid: Type.Integer(), + name: Type.String({ + description: 'full name', + examples: ['Alex Johnson'], + }), + isActive: Type.Boolean(), + avatar: Type.Optional( + Type.String({ format: 'uri' }), + ), + achievements: Type.Tuple([ + Type.Number({ minimum: 0 }), // points + // NOTE: different + // Type.Enum({ + // NOVICE: 'novice', + // PRO: 'pro', + // EXPERT: 'expert', + // MASTER: 'master', + // }), + + // NOTE: equivalent output + Type.Unsafe({ + enum: ['novice', 'pro', 'expert', 'master'], + }), + ]), + interests: Type.Array( + Type.String({ + minLength: 4, + maxLength: 36, + }), + ), + last_updated: Type.Integer({ + minimum: 0, + examples: [1722642982], + description: 'unix seconds', + }), + }); +});