convex-js
convex-js copied to clipboard
optimize ApiFromModules type performance
This pull request optimizes ApiFromModules and adds type-level benchmarks using @ark/attest so that they can be tested and added to CI if desired.
A large portion of the diff will consist of fake_chef files copied from a generated Convex project as a realistic benchmark and can generally be ignored. All meaningful optimizations occurred in src/server/api.ts.
The biggest improvements come from avoiding the creation of intermediate object types, additional intersections, and adding a fast path for modules with no segmented (i.e. A/B) paths.
This lead to a ~27% improvement in type performance on the fast path and ~14% for segmented modules. Similar strategies could be applied to other types in the repo for further improvements, but generally I found the types I reviewed to be relatively efficient and well-written, so props to the team 👏
As mentioned to @thomasballinger, another promising avenue for followup type optimization would be deduplicating object literals defined in _generated/api.d.ts. Here's an example of how that could be achieved:
// current
export declare const components: {
rateLimiter: {
lib: {
checkRateLimit: FunctionReference<
"query",
"internal",
{
config:
| {
capacity?: number
kind: "token bucket"
maxReserved?: number
period: number
rate: number
shards?: number
}
| {
capacity?: number
kind: "fixed window"
maxReserved?: number
period: number
rate: number
shards?: number
start?: number
}
count?: number
key?: string
name: string
reserve?: boolean
throws?: boolean
},
| { ok: true; retryAfter?: number }
| { ok: false; retryAfter: number }
>
}
}
}
// example optimization (should be reused for other components as well)
interface BaseConfig {
capacity?: number
maxReserved?: number
period: number
rate: number
shards?: number
}
interface FixedWindowConfig extends BaseConfig {
kind: "fixed window"
start?: number
}
interface TokenBucketConfig extends BaseConfig {
kind: "token bucket"
}
interface CommonArgs {
config: FixedWindowConfig | TokenBucketConfig
count?: number
key?: string
name: string
reserve?: boolean
throws?: boolean
}
type ReturnType =
| { ok: true; retryAfter?: number }
| { ok: false; retryAfter: number }
export declare const components: {
rateLimiter: {
lib: {
checkRateLimit: FunctionReference<
"query",
"internal",
CommonArgs,
ReturnType
>
}
}
}
Applying a similar approach to a large number of object literals in Prisma's generated types led to a ~50% performance improvement, so this could be very impactful for large projects with many such components.
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.