Skip to content

fix(go): optimize Go SDK generator performance for large APIs#14129

Closed
lifanzou wants to merge 4 commits intomainfrom
lifanzou/go-v2-perf-fix
Closed

fix(go): optimize Go SDK generator performance for large APIs#14129
lifanzou wants to merge 4 commits intomainfrom
lifanzou/go-v2-perf-fix

Conversation

@lifanzou
Copy link
Copy Markdown
Contributor

Summary

  • Precise import tracking in test file generation: bypasses expensive removeUnusedImports → AST parse → format.Node round-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 71MB types_test.go).
  • File-level parallelization in generateModelTypes: splits type generation into write → format in parallel → collect phases. Benefits multi-file APIs where each file's removeUnusedImports call runs concurrently.
  • Shared DynamicSnippetsGenerator in 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)

Baseline Optimized Improvement
Wall clock (v1 only) 21.3s 12.2s 9.1s (43%)
CPU time 27.0s 15.2s 11.8s (44%)

Seed snapshot changes

  • 39 test files: unused json/require imports removed (these were previously added then stripped by removeUnusedImports)
  • 2 empty test files deleted (contained only a package declaration with no test functions)
  • Zero non-test file changes

Test plan

  • go build ./... and go vet ./... pass
  • go test ./... passes (Go v1 unit tests)
  • pnpm turbo run compile --filter @fern-api/go-sdk passes (v2 TypeScript)
  • pnpm seed test --generator go-sdk --skip-scripts: 130/136 passed, 6 expected failures
  • pnpm seed test --generator go-model --skip-scripts: 113/113 passed
  • All seed output changes are test-file-only (unused import removal + 2 empty file deletions)

🤖 Generated with Claude Code

@lifanzou lifanzou self-assigned this Mar 26, 2026
Copy link
Copy Markdown

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@github-actions
Copy link
Copy Markdown
Contributor

🌱 Seed Test Selector

Select languages to run seed tests for:

  • Python
  • TypeScript
  • Java
  • Go
  • Ruby
  • C#
  • PHP
  • Swift
  • Rust
  • OpenAPI
  • Postman

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.

Barry and others added 2 commits March 27, 2026 10:47
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>
@lifanzou lifanzou force-pushed the lifanzou/go-v2-perf-fix branch from f7b2978 to e0c144f Compare March 27, 2026 17:47
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>
@lifanzou lifanzou force-pushed the lifanzou/go-v2-perf-fix branch from df5a852 to cead211 Compare March 30, 2026 19:28
@lifanzou lifanzou closed this Apr 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant