feat/perf: more speed boost + logging improvements#3828
Conversation
|
|
|
@SukkaW is attempting to deploy a commit to the Hey API Team on Vercel. A member of the Team first needs to authorize it. |
🦋 Changeset detectedLatest commit: 6e5249f The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
TL;DR — Broad performance sweep across the code generation pipeline: pre-computes serialized cache keys in the symbol registry, converts synchronous file I/O to parallel async writes, swaps the Key changes
Summary | 13 files | 13 commits | base: Pre-computed serialization and inlined cache registration in
|
There was a problem hiding this comment.
Solid set of optimizations. The registry pre-computation, iterative DFS, and walkDeclarations bucketing all look correct. A couple of items below worth addressing.
Task list (8/8 completed)
- Read the PR diff and identify major areas of change
- Read and review registry.ts changes
- Read and review YAML parser + package.json changes
- Read and review openapi-python changes
- Read and review openapi-ts changes
- Read and review shared/graph changes
- Verify race condition risk in concurrent writes
- Self-critique and submit review
|
Acknowledged the author's response on the Task list (3/3 completed)
|
|
Acknowledged the author's reasoning on the "render" label — no code change needed. The label aptly distinguishes the in-memory output generation phase from the disk-write phase. Task list (1/1 completed)
|
|
Acknowledged the author's note that Task list (3/3 completed)
|
|
No code changes needed — the Task list (4/4 completed)
|
|
Acknowledged the author's reply — the Task list (3/3 completed)
|
|
Reviewed PR #3828 — no blocking issues found. All performance optimizations (iterative DFS, pre-computed index serialization, single-pass walk bucketing, Task list (6/6 completed)
|
There was a problem hiding this comment.
Reviewed — no issues found.
Solid set of performance improvements with clean, well-commented implementations. The iterative post-order DFS replacing recursive collectPointerDependencies is the most substantial change and handles cycles correctly via the inStack guard. Pre-computing serialized index entries in IndexEntry[2] is a straightforward win that eliminates repeated JSON.stringify calls. The walkDeclarations single-pass bucketing and the regex-to-lastIndexOf replacement for scope seeding are both correct (the lastIndexOf approach is actually more precise than the old regex for pathological segment names).
Minor observation: openapi-ts/output.ts still uses sync fs.existsSync/fs.rmSync for the clean step (lines 16-17) while openapi-python/output.ts was fully converted to async fsPromises.access/fsPromises.rm. Not blocking — just an inconsistency to optionally align.
Task list (6/6 completed)
- Read the PR diff and identify major areas of change
- Review registry.ts changes (symbol registry)
- Review graph walk and utils changes (shared package)
- Review createClient and output changes (openapi-ts + openapi-python)
- Review dependency changes (yaml parser, package.json, lock)
- Self-critique and submit review
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #3828 +/- ##
==========================================
+ Coverage 39.57% 39.59% +0.02%
==========================================
Files 532 532
Lines 19544 19561 +17
Branches 5817 5825 +8
==========================================
+ Hits 7734 7746 +12
- Misses 9568 9573 +5
Partials 2242 2242
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
@hey-api/codegen-core
@hey-api/json-schema-ref-parser
@hey-api/nuxt
@hey-api/openapi-ts
@hey-api/shared
@hey-api/spec-types
@hey-api/types
@hey-api/vite-plugin
commit: |
|
@pullfrog how do you feel about the pull request now? Is everything resolved? |
|
Yes — everything from my reviews is resolved. All four threads from the initial review were addressed (two via |

Logging Improvement
The logging now prints how many files were written, and the time usage in
parse,render, andwriting:Performance Improvement
Replace
yamlwithjs-yamlin the YAML parser@mrlubos In the end, I decided to make the switch still. For both Cloudflare (single huge YAML spec) and Redfish (a large quantity of ref YAML specs), I see a consistent 1+ second drop, from 11 seconds down to 9~10 seconds, so it is still a 9% improvements.
We don't actually ship
@types/js-yamlto the user, it remains as a devDeps, we don't expose any YAML option in the first place.Optimize
walkDeclarations(single iteration)Previously, the
preferGroupspath made multiple loops over all pointers (one per group to find matches, plus an unmatched pass). Replaced with a single loop that buckets each pointer directly into its group orunmatched[], then emits in order.Replace
collectPointerDependencieswith a single iterative post-order DFSThe previous implementation called itself recursively from an outer loop, which is now replaced with a single iterative post-order DFS:
inStackSet replaces NvisitedSet allocations.childrenPushedmarks first vs post-order visits on the explicit stack — no recursion.graph.transitiveDependencies/graph.subtreeDependencies— no intermediate cache or double-write.collectPointerDependencies,Cache, andPointerDependenciesResulttypes removed.Pre-compute serialized index entries in
SymbolRegistryserializeIndexEntry(JSON.stringify) was called multiple times per entry acrosscacheKeyFromKeySpace,registerCacheDependencies, andinvalidateCache. The serialized string is now computed once inbuildIndexKeySpaceand stored asentry[2], read as a plain field everywhere else. Also eliminated an intermediatestring[]allocation inregisterCacheDependenciesby storing theIndexKeySpacereference directly in_cacheDependencies.