Skip to content

Native token lookup allocates a visitor on each AST descent step #64929

Open

Description

@Tom4ikss

Acknowledgement

  • I acknowledge that issues using this template may be closed without further explanation at the maintainer's discretion.

Comment

Related PR: #64928.

astnav.getTokenAtPosition calls VisitEachChildAndJSDoc at each descent step. The helper creates a new NodeVisitor and its hooks each time, although the callbacks stay the same throughout a lookup.

Profiling a tool that queries types through the native API showed these repeated allocations. Reusing the visitor reduced allocations in the isolated lookup benchmark below. The full workload did not show a clear timing improvement.

Reproduction

Base revision: a91e938. Environment: Go 1.27.1, darwin-arm64, Apple M3 Pro. I have not investigated when this behavior was introduced.

Append this benchmark to tsc/internal/astnav/tokens_test.go on the base revision (the file already has the imports):

func BenchmarkGetTokenAtPositionNested(b *testing.B) {
	text := "const value = " + strings.Repeat("call(", 24) + "target" + strings.Repeat(")", 24) + ";"
	file := parser.ParseSourceFile(ast.SourceFileParseOptions{FileName: "/test.ts", PathKey: "/test.ts"}, text, core.ScriptKindTS)
	position := strings.Index(text, "target")
	b.ReportAllocs()
	for b.Loop() {
		if token := astnav.GetTokenAtPosition(file, position); token == nil || token.Kind != ast.KindIdentifier {
			b.Fatal("target token not found")
		}
	}
}

Run from the repository root:

go -C tsc test ./internal/astnav -run '^$' -bench BenchmarkGetTokenAtPositionNested -benchmem -count=5

Results

Medians of five runs, comparing the base revision with the visitor-reuse patch in #64928:

Before After
Time 6.87 µs/op 1.24 µs/op
Allocated bytes 41,536 B/op 1,664 B/op
Allocations 153/op 13/op

This benchmark measures an identifier lookup inside 24 nested calls. The proposed change creates one visitor per lookup and reuses it during descent, while retaining child and JSDoc traversal and the exported helper signature. These measurements do not establish an overall compiler or language-service speedup.

AI assistance: Codex assisted in authoring and testing the patch and preparing this report.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions