A
arktype•2mo ago
mihajm

Some performance struggles

Hey, I seem to be having some performance issues & I'm wondering if there are more optimal ways of typing stuff out 🙂 I've added the schema I'm working with bellow, importing anything except for the inferred type really seems to make things chug
22 Replies
ssalbdivad
ssalbdivad•2mo ago
Looks pretty good overall! The things I'd probably change are: - Prefer adding ? to the key to .optional() or ? in the value - You can define an index signature directly in an object like "[string]": "string | undefined" instead of intersecting a Record. - You can avoid using omit by creating a base type without that property initially In terms of the types themselves, see if you can find a way to define them that avoids intersecting with unions. It has to compute it for each branch and it can get complex quickly. So maybe in the name case, you could add name to those branches individually and see if that helps. It seems like the last type is where TS struggles the most
mihajm
mihajmOP•2mo ago
Thanks for the tips 🙂 ill mess around with some variations & ts traces tomorrow and hopefully ill be able to find a "fast" solution.
ssalbdivad
ssalbdivad•2mo ago
Curious to see what you find! I was surprised that I could see some lag on these types despite them being relatively limited. There are other approaches we could take to try to optimize them further but starting with this stuff first makes sense, especially if you can avoid that last intersection
mihajm
mihajmOP•2mo ago
Is the TS server able to cache the infered outputs? Or would providing types as in type<MyType>(...) help? 🙂 yeah these ones i can mold quite a bit, but it had me worried for a second since we have much deeper types in our system 🙂
ssalbdivad
ssalbdivad•2mo ago
It should be able to cache them, but definitely there's a trick you can use to get nominal types that I think especially helps in terms of readability. Would also be interesting to get some 1:1 perf comparisons on using it to see what difference it makes there You don't want to pass the type param directly since that param is actually for the definition
const _user = type({
name: "string"
})

interface User extends type.infer<typeof _user> {}

const user: type<User> = _user
const _user = type({
name: "string"
})

interface User extends type.infer<typeof _user> {}

const user: type<User> = _user
Something like this
mihajm
mihajmOP•2mo ago
I see 🙂 alright I'll give it a good 1-2 and post any outliers if I see them.
ssalbdivad
ssalbdivad•2mo ago
Thanks!
mihajm
mihajmOP•2mo ago
Is there a way to define optional objects in line without using scopes? I've noticed a decent performance uplift when I dont instantiate types until i need them & just define them as constant objects & utility functions that build the constant objects & is there any validation diference between something being optional or defined as [smthSchema, '|', "undefined"]? 🙂 cuz that would solve this easily 🙂 never mind...further testing shows that the performance is about equivalent 🙂
ssalbdivad
ssalbdivad•2mo ago
What do you mean about optional objects? The recommended syntax for optionality is:
const t = type({ "foo?": "string" })
const t = type({ "foo?": "string" })
It's definitely true though that especially if you are going to be deriving schemas from one another with stuff like Pick and Omit, you could use type.define to get only the standalone definitions, then use builtin operators like ... to merge them rather than relying on the utility methods and that could save you some overhead for sure. That was one of the things I was going to recommend as a next step if you were still having issues
mihajm
mihajmOP•2mo ago
Ah thats perfect then 🙂 ah ill check out type.define then I've simply been creating the schema objects (stuff id pass to type) and marking them as const 🙂
ssalbdivad
ssalbdivad•2mo ago
type.define will definitely help there since you'll have type safety, although of course that incurs some additional overhead. I would definitely try and see what kind of impact that has before moving to unvalidated objects though, you'd lose so much of the benefit at that point. I guess you would still get an error when you passed them to type but yeah, DX would feel rough
mihajm
mihajmOP•2mo ago
Hmm tbh I've found it pretty ok, the schema itself is good, so I find the entire thing intuitive enough 🙂 but I have yet to type everything again. Smthn was definitely wrong as with vs without defined types our tsc when from 75s to 2.6 Tho I assume a lot of bad stuff was written as I have yet to actually code review the types, for now I just commented them out and am testing strategies on a smaller scale 🙂
ssalbdivad
ssalbdivad•2mo ago
Hmm yeah that's very extreme. You mean just defining the definitions as standalone then passing them to types later had that much of an impact?
mihajm
mihajmOP•2mo ago
Yup, we werent using them yet, just had a someone in the team take a crack at rewriting about half our pure TS types to schemas Tho a quite a few of them have basically infinite recursion + are just complex so to be expected a bit 🙂
ssalbdivad
ssalbdivad•2mo ago
Oh I see. Well there will definitely be inevitable overhead there then, but hopefully it could be reduced a bit with type.define
mihajm
mihajmOP•2mo ago
Yup, would there also be a way of limiting recursion in say a type calling itself?
ssalbdivad
ssalbdivad•2mo ago
I actually don't think the recursion is very likely to be the core problem. There are ways you can do that internally but I don't think it would help in this situation
mihajm
mihajmOP•2mo ago
Fair enough so just the amount of branching with ands and ors?
ssalbdivad
ssalbdivad•2mo ago
Most of the overhead is probably just from all the extra validation + inference and especially merging objects with and or omit Yeah So some of that you could mitigate by predefining the objects
mihajm
mihajmOP•2mo ago
Cool, will take a shot at rewriting it with .define and hopefuly that solves it 🙂 since otherwise im loving the syntax and extensibility of arktype + ive already written a few decent size things depending on it..so itd be quite "fun" to extract it
ssalbdivad
ssalbdivad•2mo ago
I hope so too! If not, I'll try to have a look at additional optimizations at some point but overall it's unlikely I'd find a 50% improvement or anything at this point
mihajm
mihajmOP•2mo ago
Dont worry about it we'll figure smthn out 🙂 worst case we dont define EVERY type in the system as a validator 😄 or other solutions like prebuilding the modules

Did you find this page helpful?