Summary
packages.Load is called without any caching in three functions. Each call invokes the Go build system (go list) and takes 100–500ms. For large codebases, this causes the CLI to spend more time loading packages than generating code.
loadNamedType (utils.go:98-112)
Called 4 times at package init for allowedInterfaces, then again per-field via Field.Type() (generator.go:456). If 20 fields reference models.User, the same package is loaded 20 times.
loadNamedStructType (utils.go:115-150)
Called per anonymous embedding of an external type (generator.go:791). Same package loaded repeatedly for different structs.
getCurrentPackagePath (utils.go:84-95)
Called once per input file (generator.go:261). Processing 20 files in the same package triggers 20 identical loads.
Proposed Fix
Add a package-level cache keyed by (modRoot, pkgPath):
var pkgCache sync.Map // map[pkgCacheKey]*packages.Package
type pkgCacheKey struct {
modRoot string
pkgPath string
}
All three functions check the cache before calling packages.Load. Since the CLI is single-threaded during processing, even a simple map[string]*packages.Package with no synchronization would work (or sync.Map if concurrency is ever added).
Expected Impact
On a project with 50 structs across 20 files:
- Before: 100+
packages.Load calls → potentially minutes
- After: 1 call per unique package path → seconds
Diagnosis
Run with GODEBUG=gocacheverify=1 or add timing around packages.Load calls to confirm this dominates CLI runtime.
Summary
packages.Loadis called without any caching in three functions. Each call invokes the Go build system (go list) and takes 100–500ms. For large codebases, this causes the CLI to spend more time loading packages than generating code.loadNamedType(utils.go:98-112)Called 4 times at package init for
allowedInterfaces, then again per-field viaField.Type()(generator.go:456). If 20 fields referencemodels.User, the same package is loaded 20 times.loadNamedStructType(utils.go:115-150)Called per anonymous embedding of an external type (
generator.go:791). Same package loaded repeatedly for different structs.getCurrentPackagePath(utils.go:84-95)Called once per input file (
generator.go:261). Processing 20 files in the same package triggers 20 identical loads.Proposed Fix
Add a package-level cache keyed by
(modRoot, pkgPath):All three functions check the cache before calling
packages.Load. Since the CLI is single-threaded during processing, even a simplemap[string]*packages.Packagewith no synchronization would work (orsync.Mapif concurrency is ever added).Expected Impact
On a project with 50 structs across 20 files:
packages.Loadcalls → potentially minutesDiagnosis
Run with
GODEBUG=gocacheverify=1or add timing aroundpackages.Loadcalls to confirm this dominates CLI runtime.