我制作了速度快 1000 倍的 TypeScript 验证器库
您好,我是typescript-json的开发者,最近进行了一项性能基准测试,与其他竞争库进行了比较。测试结果表明,我的typescript-json库的速度比zod最高快 1000 倍。
我为这样的性能提升感到自豪,并希望更多 TypeScript 开发者能够采用我的库。typescript -json的优势不仅在于性能更佳,而且使用起来也非常简单。typescript -json不需要任何额外的模式定义,只需要一行纯 TypeScript 类型代码即可。那么,用我的typescript-json库来代替io-ts或zod怎么样?
// ALLOW SUPERFLUOUS PROPERTIES
export function is<T>(input: T): boolean; // true or false
export function assertType<T>(input: T): T; // throws `TypeGuardError`
export function validate<T>(input: T): IValidation; // detailed reasons
// DO NOT ALLOW SUPERFLUOUS PROPERTIES
export function equals<T>(input: T): boolean;
export function assertEquals<T>(input: T): T;
export function validateEquals<T>(input: T): IValidation;
附言:当然,由于本次基准测试由我本人进行,难免有人会质疑其客观性。因此,为了确保客观性,我公开了基准测试中使用的所有代码。以下代码用于基准测试。您也可以下载这个typescript-json 文件npm run benchmark
,然后通过运行命令来运行基准测试程序。
is()
功能
export function is<T>(input: T): boolean;
在 Intel i5-1135g7、Surface Pro 8 上测量
直到运行这个基准测试程序,我才知道zod非常慢。io -ts也比typescript-json和ajv慢大约 8 倍,但与zod相比,它的性能缓慢看起来不算什么。
更令人吃惊的是,ajv需要 JSON 模式定义才能验证,但它无法验证 JSON 模式类型本身。虽然其他库io-ts和zod也验证 JSON 模式定义失败,但ajv难道不是和它们不一样吗?而且,当遇到复杂类型时,ajv在大多数情况下会因为运行时错误而崩溃。
validate()
功能
export function validate<T>(input): IValidation;
export interface IValidation {
success: boolean;
errors: IValidation.IError[];
}
export namespace IValidation {
export interface IError {
path: string;
expected: string;
value: any;
}
}
在 Intel i5-1135g7、Surface Pro 8 上测量
不幸的是,无法衡量ajv的性能,因为它不支持描述详细错误原因的验证功能。
无论如何,虽然zod即使在函数方面也是最慢的库,但与其他库的性能差距却显著缩小了。此外,与typescript-json和io-tsvalidate()
的性能差距时大时小。
顺便说一句,在测试zod的时候,我有时会怀疑自己:“我是不是搞错了?” 但实际上并没有出错,所以我就纳闷为什么zod这么慢。为了分析原因,我阅读了zod的源代码,以下是我的结论。
虽然zod是所有验证器中速度最慢的,但错误原因比io-ts更详细、更准确,因此其
validate()
功能上的表现较慢也是可以理解的。另外,zod没有为
is()
函数实现专门的逻辑,也没有允许用户复用该validate()
函数。因此,当zod实现独立的is()
函数算法时,我认为它的性能可以超越io-ts。
TypeScript 类型的完整规范
typescript-json比io-ts和zod更快、更易用。但这还不是全部。typescript -json可以验证完整的 TypeScript 类型规范。下表列出了竞争性运行时验证器库支持的规范表。从下表可以看出,只有typescript-json可以验证复杂的联合类型。
成分 | TSON |
ajv |
io-ts |
zod |
C.V. |
---|---|---|---|---|---|
便于使用 | ✅ | ❌ | ❌ | ❌ | ❌ |
对象(简单) | ✔ | ✔ | ✔ | ✔ | ✔ |
对象(分层) | ✔ | ❌ | ✔ | ✔ | ✔ |
对象(递归) | ✔ | ❌ | ✔ | ✔ | ✔ |
对象(联合,隐式) | ✅ | ❌ | ❌ | ❌ | ❌ |
对象(联合,显式) | ✔ | ✔ | ✔ | ✔ | ❌ |
对象(附加标签) | ✔ | ✔ | ✔ | ✔ | ✔ |
对象(模板文字类型) | ✔ | ✔ | ❌ | ❌ | ❌ |
对象(动态属性) | ✔ | ✔ | ❌ | ❌ | ❌ |
数组(分层) | ✔ | ✔ | ✔ | ✔ | ✔ |
数组(递归) | ✔ | ❌ | ✔ | ✔ | ✔ |
数组(递归、联合) | ✔ | ❌ | ✔ | ✔ | ❌ |
数组(R+U,隐式) | ✅ | ❌ | ❌ | ❌ | ❌ |
终极联合类型 | ✅ | ❌ | ❌ | ❌ | ❌ |