Skip to content

Commit

Permalink
Cache the evaluation of ParseInputLazyPath.path() for a moderate perf…
Browse files Browse the repository at this point in the history
… improvement (#2137)

* Cache the evaluation of ParseInputLazyPath.path()

A ParseInput's path may be evaluated multiple times,
so caching the evaluation result avoids some extra
array allocations.

Around a 10% speedup on 'realworld'.

* Simplify

* Revert "Simplify"

This reverts commit c1b94a2.

---------

Co-authored-by: Colin McDonnell <colinmcd94@gmail.com>
  • Loading branch information
jussisaurio and colinhacks committed Mar 5, 2023
1 parent d8e8653 commit 03c0ab1
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 14 deletions.
2 changes: 2 additions & 0 deletions deno/lib/README.md
Expand Up @@ -608,6 +608,8 @@ z.string().trim(); // trim whitespace
z.string().toLowerCase(); // toLowerCase
z.string().toUpperCase(); // toUpperCase
```
<!-- z.string().toLowerCase(); // toLowerCase -->
<!-- z.string().toUpperCase(); // toUpperCase -->

> Check out [validator.js](https://github.com/validatorjs/validator.js) for a bunch of other useful string validation functions that can be used in conjunction with [Refinements](#refine).
Expand Down
23 changes: 16 additions & 7 deletions deno/lib/types.ts
Expand Up @@ -63,6 +63,7 @@ class ParseInputLazyPath implements ParseInput {
data: any;
_path: ParsePath;
_key: string | number | (string | number)[];
_cachedPath: ParsePath = [];
constructor(
parent: ParseContext,
value: any,
Expand All @@ -75,7 +76,15 @@ class ParseInputLazyPath implements ParseInput {
this._key = key;
}
get path() {
return this._path.concat(this._key);
if (!this._cachedPath.length) {
if (this._key instanceof Array) {
this._cachedPath.push(...this._path, ...this._key);
} else {
this._cachedPath.push(...this._path, this._key);
}
}

return this._cachedPath;
}
}

Expand Down Expand Up @@ -3772,7 +3781,7 @@ export class ZodFunction<
return this._def.returns;
}

args<Items extends Parameters<(typeof ZodTuple)["create"]>[0]>(
args<Items extends Parameters<typeof ZodTuple["create"]>[0]>(
...items: Items
): ZodFunction<ZodTuple<Items, ZodUnknown>, Returns> {
return new ZodFunction({
Expand Down Expand Up @@ -4910,18 +4919,18 @@ const oboolean = () => booleanType().optional();

export const coerce = {
string: ((arg) =>
ZodString.create({ ...arg, coerce: true })) as (typeof ZodString)["create"],
ZodString.create({ ...arg, coerce: true })) as typeof ZodString["create"],
number: ((arg) =>
ZodNumber.create({ ...arg, coerce: true })) as (typeof ZodNumber)["create"],
ZodNumber.create({ ...arg, coerce: true })) as typeof ZodNumber["create"],
boolean: ((arg) =>
ZodBoolean.create({
...arg,
coerce: true,
})) as (typeof ZodBoolean)["create"],
})) as typeof ZodBoolean["create"],
bigint: ((arg) =>
ZodBigInt.create({ ...arg, coerce: true })) as (typeof ZodBigInt)["create"],
ZodBigInt.create({ ...arg, coerce: true })) as typeof ZodBigInt["create"],
date: ((arg) =>
ZodDate.create({ ...arg, coerce: true })) as (typeof ZodDate)["create"],
ZodDate.create({ ...arg, coerce: true })) as typeof ZodDate["create"],
};

export {
Expand Down
23 changes: 16 additions & 7 deletions src/types.ts
Expand Up @@ -63,6 +63,7 @@ class ParseInputLazyPath implements ParseInput {
data: any;
_path: ParsePath;
_key: string | number | (string | number)[];
_cachedPath: ParsePath = [];
constructor(
parent: ParseContext,
value: any,
Expand All @@ -75,7 +76,15 @@ class ParseInputLazyPath implements ParseInput {
this._key = key;
}
get path() {
return this._path.concat(this._key);
if (!this._cachedPath.length) {
if (this._key instanceof Array) {
this._cachedPath.push(...this._path, ...this._key);
} else {
this._cachedPath.push(...this._path, this._key);
}
}

return this._cachedPath;
}
}

Expand Down Expand Up @@ -3772,7 +3781,7 @@ export class ZodFunction<
return this._def.returns;
}

args<Items extends Parameters<(typeof ZodTuple)["create"]>[0]>(
args<Items extends Parameters<typeof ZodTuple["create"]>[0]>(
...items: Items
): ZodFunction<ZodTuple<Items, ZodUnknown>, Returns> {
return new ZodFunction({
Expand Down Expand Up @@ -4910,18 +4919,18 @@ const oboolean = () => booleanType().optional();

export const coerce = {
string: ((arg) =>
ZodString.create({ ...arg, coerce: true })) as (typeof ZodString)["create"],
ZodString.create({ ...arg, coerce: true })) as typeof ZodString["create"],
number: ((arg) =>
ZodNumber.create({ ...arg, coerce: true })) as (typeof ZodNumber)["create"],
ZodNumber.create({ ...arg, coerce: true })) as typeof ZodNumber["create"],
boolean: ((arg) =>
ZodBoolean.create({
...arg,
coerce: true,
})) as (typeof ZodBoolean)["create"],
})) as typeof ZodBoolean["create"],
bigint: ((arg) =>
ZodBigInt.create({ ...arg, coerce: true })) as (typeof ZodBigInt)["create"],
ZodBigInt.create({ ...arg, coerce: true })) as typeof ZodBigInt["create"],
date: ((arg) =>
ZodDate.create({ ...arg, coerce: true })) as (typeof ZodDate)["create"],
ZodDate.create({ ...arg, coerce: true })) as typeof ZodDate["create"],
};

export {
Expand Down

0 comments on commit 03c0ab1

Please sign in to comment.