Value.Parse and underlying functions performance #1141
Closed
denis-ilchishin
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Hi @sinclairzx81, I've been playing around with Typebox and I'm a bit concerned about the performance of Value.Default, Value.Clean, etc.
I've created a simple playground repo to do some benchmarking and here's some preview:
I'm completely aware that micro-benchmarking is not very representative, and there's ton of different things that can impact the performace, as well as fundamental difference between how zod and typebox operate. Therefore, this numbers are just for a reference and something to base the conversation on.
From my inverstigation, unions, nested object and arrays have the biggest impact on performance, which sounds very reasonable. Well, why that is the case is also pretty obvious: by the architectural design, all the actions (apply default values, clean extra properties, etc..) are built to be independetly consumable. But this leads to a not very satisfactory performance, when for some usecase its requried to pass a value through Typebox parse pipeline with multiple actions — most of which deeply traverse the value — therefore doing pretty expensive recursive traverse operations for EACH step. And this one of the biggest differences of how zod operates (does all the validations, default values resolution, extra properties cleanup, etc. in one go).
Another thing that I noticed is that, for example, for Value.Default to correctly resolve and apply default values for union types, its necessary to run Check on the value for each subschema/subtype to figure out the schema to take the default value from. But in this case it always uses runtime validation, which can be significantly slower compared to a complied validation (example from typebox's readme)
So, I've been wondering, if there's room for improvement here? Do you see any way to optimize it? Here's couple of things I think about:
for every action, make it that the list of actions to be performed is passed to each type specific function
check
functions of all nested types/schemas, so they can be passed to a Value.Default and be accessed there, just like you do with references, something like this:Beta Was this translation helpful? Give feedback.
All reactions