Skip to content

x/tools/go/types/objectpath: reduce allocations with sync.Pool #77059

@ewhauser

Description

@ewhauser

Summary

The objectpath.Encoder.For() function allocates heavily, causing significant GC pressure in tools that call it frequently (e.g., static analyzers like nilaway that compute object paths for cross-package inference).

Problem

Profiling nogo with ~40 analyzers on a large monorepo (~9000 packages) revealed that objectpath functions consumed 504MB (60%) of allocations on hot packages:

271MB (32%) objectpath.(*finder).find
101MB (12%) strconv.AppendInt
68MB (8%) objectpath.(*Encoder).For
65MB (8%) objectpath.appendOpArg

The main allocation sources are:

  1. make([]byte, 0, 48) in Encoder.For() - allocated per call
  2. strconv.AppendInt in appendOpArg - allocates for each method/field index
  3. &finder{} in find() - new struct per search with lazily-allocated maps

Proposed Solution

  1. Pool path buffers using sync.Pool instead of allocating per call
  2. Pre-compute small integers (0-99) to avoid strconv.AppendInt for common indices
  3. Pool finder structs with pre-allocated maps, using clear() to reset between uses

Results

On a package with heavy objectpath usage:

Metric Before After Improvement
Allocations 929MB 445MB 52% reduction
GC cycles 21 14 33% reduction
GC pause 1.77ms 0.81ms 54% reduction

After the change, objectpath functions no longer appear in the top allocators.

Patch

I have a working patch ready to submit as a PR. The changes are backward-compatible and do not change any public APIs.

/cc @adonovan @findleyr

Metadata

Metadata

Assignees

No one assigned

    Labels

    ImplementationIssues describing a semantics-preserving change to the Go implementation.NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.ToolsThis label describes issues relating to any tools in the x/tools repository.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions