fix(go): optimize Go SDK generator performance for large APIs#14129
Closed
fix(go): optimize Go SDK generator performance for large APIs#14129
Conversation
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review to trigger a review.
Tip: disable this comment in your organization's Code Review settings.
Contributor
🌱 Seed Test SelectorSelect languages to run seed tests for:
How to use: Click the ⋯ menu above → "Edit" → check the boxes you want → click "Update comment". Tests will run automatically and snapshots will be committed to this PR. |
Reduce Go v1 generator wall-clock time by ~43% on large APIs (Stripe: 21s → 12s) through three targeted optimizations: 1. Precise import tracking in test file generation (file_writer.go): Track which imports are actually referenced during test generation and write them directly, bypassing the expensive removeUnusedImports → AST parse → format.Node round-trip. This eliminates ~12s of CPU time on Stripe's 71MB types_test.go. 2. File-level parallelization in generateModelTypes (generator.go): Split into 3 phases: write types to buffers → format files in parallel via goroutines → collect results in deterministic order. Benefits multi-file APIs where each file's formatting runs concurrently. 3. Shared DynamicSnippetsGenerator in v2 (SdkGeneratorCli.ts): Create one DynamicSnippetsGenerator for both README and Reference snippet generation instead of two, avoiding duplicate IR conversion. Seed snapshot changes: unused imports removed from test files that don't have JSON marshaling tests. Two empty test files (with only a package declaration) are no longer generated. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The TestSettersMarkExplicit test section uses json.Marshal/Unmarshal and require.NoError, but the precise import tracking only checked jsonMarshalingTests. Now also checks if any setter tests were written. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
f7b2978 to
e0c144f
Compare
1. Extract shared assembleFile() helper to deduplicate File() and fileWithPreciseImports() — ensures header format and import ordering changes only need updating in one place. 2. Replace ad-hoc wroteSetterTests/usedAliases tracking with testImportTracker struct. Each Write*Tests call site registers its imports on the tracker, making it explicit what imports each test type needs. Adding a new test type that uses a new import now has a clear registration point rather than a fragile side-channel. 3. Add concurrency safety comment on the goroutine pattern in generateModelTypes explaining why unbounded parallelism is safe. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
df5a852 to
cead211
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
removeUnusedImports→ AST parse →format.Noderound-trip for generated test files by tracking which imports are actually referenced during generation. Eliminates ~12s of CPU time on large APIs (e.g. Stripe's 71MBtypes_test.go).generateModelTypes: splits type generation into write → format in parallel → collect phases. Benefits multi-file APIs where each file'sremoveUnusedImportscall runs concurrently.DynamicSnippetsGeneratorin Go v2: creates one shared instance for both README and Reference snippet generation instead of two, avoiding duplicate IR conversion.Profiling data (Stripe, 10,357 types)
Seed snapshot changes
json/requireimports removed (these were previously added then stripped byremoveUnusedImports)Test plan
go build ./...andgo vet ./...passgo test ./...passes (Go v1 unit tests)pnpm turbo run compile --filter @fern-api/go-sdkpasses (v2 TypeScript)pnpm seed test --generator go-sdk --skip-scripts: 130/136 passed, 6 expected failurespnpm seed test --generator go-model --skip-scripts: 113/113 passed🤖 Generated with Claude Code