From 6d149e811a2999a539ba72bd2e107eef984d858a Mon Sep 17 00:00:00 2001 From: "lilong.21" Date: Mon, 9 Mar 2026 14:45:45 +0800 Subject: [PATCH 1/4] perf: improve IsStandardPackage --- lang/golang/parser/utils.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lang/golang/parser/utils.go b/lang/golang/parser/utils.go index e657b0bb..808253b7 100644 --- a/lang/golang/parser/utils.go +++ b/lang/golang/parser/utils.go @@ -112,6 +112,13 @@ func (pc *PackageCache) IsStandardPackage(path string) bool { return isStd } + // Optimization: if the first segment of the path contains a dot, it's likely a domain name (e.g. github.com), + // so it's not a standard package. This avoids expensive build.Import calls. + if parts := strings.SplitN(path, "/", 2); len(parts) > 0 && strings.Contains(parts[0], ".") { + pc.set(path, false) + return false + } + pkg, err := build.Import(path, "", build.FindOnly) if err != nil { // Cannot find the package, assume it's not a standard package From 5298babd14bf4b426b06194b79777c09e59fb1c8 Mon Sep 17 00:00:00 2001 From: "lilong.21" Date: Mon, 9 Mar 2026 17:17:45 +0800 Subject: [PATCH 2/4] perf: improve IsStandardLibrary --- lang/golang/parser/utils.go | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/lang/golang/parser/utils.go b/lang/golang/parser/utils.go index 808253b7..d4714523 100644 --- a/lang/golang/parser/utils.go +++ b/lang/golang/parser/utils.go @@ -18,13 +18,13 @@ import ( "container/list" "fmt" "go/ast" - "go/build" "go/types" "os" "os/exec" "path" "path/filepath" "regexp" + "runtime" "strings" "sync" @@ -112,27 +112,27 @@ func (pc *PackageCache) IsStandardPackage(path string) bool { return isStd } - // Optimization: if the first segment of the path contains a dot, it's likely a domain name (e.g. github.com), - // so it's not a standard package. This avoids expensive build.Import calls. - if parts := strings.SplitN(path, "/", 2); len(parts) > 0 && strings.Contains(parts[0], ".") { - pc.set(path, false) - return false - } + isStd := IsStandardLibrary(path) + pc.set(path, isStd) + return isStd +} - pkg, err := build.Import(path, "", build.FindOnly) - if err != nil { - // Cannot find the package, assume it's not a standard package - pc.set(path, false) +func IsStandardLibrary(pkgPath string) bool { + + goroot := runtime.GOROOT() + if goroot == "" { return false } - isStd := pkg.Goroot - pc.set(path, isStd) + dir := filepath.Join(goroot, "src", pkgPath) + info, err := os.Stat(dir) + isStd := err == nil && info.IsDir() + return isStd } // stdlibCache 缓存 importPath 是否是 system package, 10000 个缓存 -var stdlibCache = NewPackageCache(10000) +var stdlibCache = NewPackageCache(100000) func isSysPkg(importPath string) bool { return stdlibCache.IsStandardPackage(importPath) From b6ca0c3dc80814b61eb3151714fde57a627c6764 Mon Sep 17 00:00:00 2001 From: "lilong.21" Date: Mon, 9 Mar 2026 21:24:22 +0800 Subject: [PATCH 3/4] perf: git commit --- lang/golang/parser/utils.go | 9 ++++++++- lang/golang/parser/utils_test.go | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/lang/golang/parser/utils.go b/lang/golang/parser/utils.go index d4714523..2312f00e 100644 --- a/lang/golang/parser/utils.go +++ b/lang/golang/parser/utils.go @@ -318,14 +318,21 @@ func isUpperCase(c byte) bool { return c >= 'A' && c <= 'Z' } +var commitHashCache sync.Map + func getCommitHash(dir string) (string, error) { + if val, ok := commitHashCache.Load(dir); ok { + return val.(string), nil + } cmd := exec.Command("git", "rev-parse", "HEAD") cmd.Dir = dir output, err := cmd.Output() if err != nil { return "", fmt.Errorf("failed to get commit hash: %v", err) } - return strings.TrimSpace(string(output)), nil + hash := strings.TrimSpace(string(output)) + commitHashCache.Store(dir, hash) + return hash, nil } type workFile struct { diff --git a/lang/golang/parser/utils_test.go b/lang/golang/parser/utils_test.go index 301e6a1d..02e4b1b9 100644 --- a/lang/golang/parser/utils_test.go +++ b/lang/golang/parser/utils_test.go @@ -20,6 +20,7 @@ import ( "go/parser" "go/token" "go/types" + "os" "slices" "sync" "testing" @@ -285,3 +286,23 @@ func Test_isSysPkg(t *testing.T) { assert.False(t, foundOs, "os should have been evicted from the cache") }) } + +func Test_getCommitHash(t *testing.T) { + wd, err := os.Getwd() + require.NoError(t, err) + + // First call, should execute git command + hash1, err := getCommitHash(wd) + require.NoError(t, err) + require.NotEmpty(t, hash1) + + // Second call, should come from cache + hash2, err := getCommitHash(wd) + require.NoError(t, err) + require.Equal(t, hash1, hash2) + + // Check cache directly + cached, ok := commitHashCache.Load(wd) + require.True(t, ok) + require.Equal(t, hash1, cached) +} From ff6e0383317335f91f42b6c07aefab0ecf67028f Mon Sep 17 00:00:00 2001 From: "lilong.21" Date: Mon, 9 Mar 2026 22:29:24 +0800 Subject: [PATCH 4/4] perf: cgo packages.Load --- lang/golang/parser/pkg.go | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lang/golang/parser/pkg.go b/lang/golang/parser/pkg.go index 7481650b..a577f060 100644 --- a/lang/golang/parser/pkg.go +++ b/lang/golang/parser/pkg.go @@ -185,22 +185,20 @@ func (p *GoParser) loadPackages(mod *Module, dir string, pkgPath PkgPath) (err e Mode: baseOpts, Fset: fset, Dir: dir, + Env: append(os.Environ(), "GOSUMDB=off"), } if p.opts.NeedTest { cfg.Tests = true } - pkgs, err := packages.Load(cfg, pkgPath) - if err != nil { - return fmt.Errorf("load path '%s' failed: %v", dir, err) - } - hasCGO := false if len(p.cgoPkgs) > 0 { hasCGO = true } - fmt.Fprintf(os.Stderr, "[loadPackages] mod: %s, dir: %s, pkgPath: %s, hasCGO: %v\n", mod.Name, dir, pkgPath, hasCGO) + + var pkgs []*packages.Package + if hasCGO { baseOpts |= packages.NeedCompiledGoFiles cfg.Mode = baseOpts @@ -208,8 +206,15 @@ func (p *GoParser) loadPackages(mod *Module, dir string, pkgPath PkgPath) (err e if err != nil { return fmt.Errorf("load path '%s' with CGO failed: %v", dir, err) } + } else { + pkgs, err = packages.Load(cfg, pkgPath) + if err != nil { + return fmt.Errorf("load path '%s' failed: %v", dir, err) + } } + fmt.Fprintf(os.Stderr, "[loadPackages] mod: %s, dir: %s, pkgPath: %s, hasCGO: %v\n", mod.Name, dir, pkgPath, hasCGO) + for _, pkg := range pkgs { if mm := p.repo.Modules[mod.Name]; mm != nil && (*mm).Packages[pkg.ID] != nil { continue