-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #71 from janglad/performance
Performance
- Loading branch information
Showing
19 changed files
with
644 additions
and
400 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,6 @@ | ||
--- | ||
"safe-fn": minor | ||
--- | ||
|
||
- About a ~10x performance increase for single `safe-fn` instances | ||
- About a ~17x performance increase when testing a `safe-fn` with 10 parents |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { safeFnAsyncBench } from "./safe-fn"; | ||
import { safeFnAsyncWithCallbacksBench } from "./safe-fn-callbacks"; | ||
import { safeFnAsyncGenBench } from "./safe-fn-gen"; | ||
import { zsaBench } from "./zsa"; | ||
|
||
const runBench = async () => { | ||
await safeFnAsyncBench.run(); | ||
console.log(safeFnAsyncBench.name); | ||
console.table(safeFnAsyncBench.table()); | ||
await safeFnAsyncGenBench.run(); | ||
console.log(safeFnAsyncGenBench.name); | ||
console.table(safeFnAsyncGenBench.table()); | ||
await zsaBench.run(); | ||
console.log(zsaBench.name); | ||
console.table(zsaBench.table()); | ||
await safeFnAsyncWithCallbacksBench.run(); | ||
console.log(safeFnAsyncWithCallbacksBench.name); | ||
console.table(safeFnAsyncWithCallbacksBench.table()); | ||
}; | ||
|
||
runBench(); |
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,19 @@ | ||
{ | ||
"private": true, | ||
"version": "0.0.0", | ||
"name": "@repo/benchmark", | ||
"devDependencies": { | ||
"@repo/typescript-config": "workspace:^", | ||
"typescript": "^5.5.4" | ||
}, | ||
"scripts": { | ||
"bench": "bun run index.ts" | ||
}, | ||
"dependencies": { | ||
"neverthrow": "^8.0.0", | ||
"safe-fn": "workspace:^", | ||
"tinybench": "^3.0.6", | ||
"zod": "^3.23.8", | ||
"zsa": "^0.6.0" | ||
} | ||
} |
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,60 @@ | ||
import { createSafeFn } from "safe-fn"; | ||
import { Bench } from "tinybench"; | ||
|
||
import { ok } from "neverthrow"; | ||
import { z } from "zod"; | ||
|
||
const schema = z.unknown(); | ||
|
||
const handlerFn = async (args: any) => ok(args); | ||
|
||
const callbackFn = async (args: any) => {}; | ||
|
||
const rootSafeFn = createSafeFn() | ||
.input(schema) | ||
.output(schema) | ||
.handler(handlerFn) | ||
.onComplete(callbackFn) | ||
.onError(callbackFn) | ||
.onSuccess(callbackFn) | ||
.onStart(callbackFn); | ||
|
||
const addSafeFn = (root: any) => { | ||
return createSafeFn() | ||
.use(root) | ||
.input(schema) | ||
.output(schema) | ||
.handler(handlerFn) | ||
.onComplete(callbackFn) | ||
.onError(callbackFn) | ||
.onSuccess(callbackFn) | ||
.onStart(callbackFn); | ||
}; | ||
|
||
const getSafeFnWithNMiddlewares = (n: number) => { | ||
let safeFn: any = rootSafeFn; | ||
for (let i = 0; i < n; i++) { | ||
safeFn = addSafeFn(safeFn); | ||
} | ||
return safeFn; | ||
}; | ||
|
||
const with10 = getSafeFnWithNMiddlewares(10); | ||
const with100 = getSafeFnWithNMiddlewares(100); | ||
const with1000 = getSafeFnWithNMiddlewares(1000); | ||
|
||
export const safeFnAsyncWithCallbacksBench = new Bench({ | ||
name: "Safe FN Middleware With Callbacks", | ||
}) | ||
.add("with1", async () => { | ||
const res = await rootSafeFn.run({}); | ||
}) | ||
.add("with10", async () => { | ||
const res = await with10.run({}); | ||
}) | ||
.add("with100", async () => { | ||
const res = await with100.run({}); | ||
}) | ||
.add("with1000", async () => { | ||
const res = await with1000.run({}); | ||
}); |
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,51 @@ | ||
import { ok } from "neverthrow"; | ||
import { createSafeFn } from "safe-fn"; | ||
import { Bench } from "tinybench"; | ||
import { z } from "zod"; | ||
|
||
const schema = z.unknown(); | ||
|
||
const handlerFn = async function* (args: any) { | ||
return ok(args); | ||
}; | ||
|
||
const rootSafeFn = createSafeFn() | ||
.input(schema) | ||
.output(schema) | ||
.safeHandler(handlerFn); | ||
|
||
const addSafeFn = (root: any) => { | ||
return createSafeFn() | ||
.use(root) | ||
.input(schema) | ||
.output(schema) | ||
.safeHandler(handlerFn); | ||
}; | ||
|
||
const getSafeFnWithNMiddlewares = (n: number) => { | ||
let safeFn: any = rootSafeFn; | ||
for (let i = 0; i < n; i++) { | ||
safeFn = addSafeFn(safeFn); | ||
} | ||
return safeFn; | ||
}; | ||
|
||
const with10 = getSafeFnWithNMiddlewares(10); | ||
const with100 = getSafeFnWithNMiddlewares(100); | ||
const with1000 = getSafeFnWithNMiddlewares(1000); | ||
|
||
export const safeFnAsyncGenBench = new Bench({ | ||
name: "Safe FN Async Gen Middleware", | ||
}) | ||
.add("with1", async () => { | ||
const res = await rootSafeFn.run({}); | ||
}) | ||
.add("with10", async () => { | ||
const res = await with10.run({}); | ||
}) | ||
.add("with100", async () => { | ||
const res = await with100.run({}); | ||
}) | ||
.add("with1000", async () => { | ||
const res = await with1000.run({}); | ||
}); |
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,50 @@ | ||
import { createSafeFn } from "safe-fn"; | ||
import { Bench } from "tinybench"; | ||
|
||
import { ok } from "neverthrow"; | ||
import { z } from "zod"; | ||
|
||
const schema = z.unknown(); | ||
|
||
const handlerFn = async (args: any) => ok(args); | ||
|
||
const rootSafeFn = createSafeFn() | ||
.input(schema) | ||
.output(schema) | ||
.handler(handlerFn); | ||
|
||
const addSafeFn = (root: any) => { | ||
return createSafeFn() | ||
.use(root) | ||
.input(schema) | ||
.output(schema) | ||
.handler(handlerFn); | ||
}; | ||
|
||
const getSafeFnWithNMiddlewares = (n: number) => { | ||
let safeFn: any = rootSafeFn; | ||
for (let i = 0; i < n; i++) { | ||
safeFn = addSafeFn(safeFn); | ||
} | ||
return safeFn; | ||
}; | ||
|
||
const with10 = getSafeFnWithNMiddlewares(10); | ||
const with100 = getSafeFnWithNMiddlewares(100); | ||
const with1000 = getSafeFnWithNMiddlewares(1000); | ||
console.log("Done with this"); | ||
export const safeFnAsyncBench = new Bench({ | ||
name: "Safe FN Middleware", | ||
}) | ||
.add("with1", async () => { | ||
const res = await rootSafeFn.run({}); | ||
}) | ||
.add("with10", async () => { | ||
const res = await with10.run({}); | ||
}) | ||
.add("with100", async () => { | ||
const res = await with100.run({}); | ||
}) | ||
.add("with1000", async () => { | ||
const res = await with1000.run({}); | ||
}); |
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,3 @@ | ||
{ | ||
"extends": "@repo/typescript-config/base.json" | ||
} |
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,51 @@ | ||
import { Bench } from "tinybench"; | ||
import { z } from "zod"; | ||
|
||
import { createServerAction, createServerActionProcedure } from "zsa"; | ||
|
||
const schema = z.unknown(); | ||
|
||
const rootProcedure = createServerActionProcedure() | ||
.input(schema) | ||
.output(schema) | ||
.handler((e) => e); | ||
|
||
const bareAction = createServerAction() | ||
.input(schema) | ||
.output(schema) | ||
.handler((e) => e); | ||
|
||
const getProcedureWithNMiddlewares = (n: number) => { | ||
let procedure: any = rootProcedure; | ||
for (let i = 1; i < n; i++) { | ||
procedure = createServerActionProcedure(procedure) | ||
.input(schema) | ||
.output(schema) | ||
.handler((e) => e); | ||
} | ||
return procedure | ||
.createServerAction() | ||
.input(schema) | ||
.output(schema) | ||
.handler((e) => e); | ||
}; | ||
|
||
const with10 = getProcedureWithNMiddlewares(10); | ||
const with100 = getProcedureWithNMiddlewares(100); | ||
const with1000 = getProcedureWithNMiddlewares(1000); | ||
|
||
export const zsaBench = new Bench({ | ||
name: "ZSA", | ||
}) | ||
.add("with1", async () => { | ||
const res = await bareAction({}); | ||
}) | ||
.add("with10", async () => { | ||
const res = await with10({}); | ||
}) | ||
.add("with100", async () => { | ||
const res = await with100({}); | ||
}) | ||
.add("with1000", async () => { | ||
const res = await with1000({}); | ||
}); |
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
Oops, something went wrong.