Skip to content

Commit fdb0da6

Browse files
committed
gopls/internal/regtest/bench: add a benchmark for diagnosing a change
Add a benchmark that measures how long it takes gopls to fully complete diagnostics from a change. Change-Id: Icb19ccf658ebe6604337283cb6e13773c3b95f18 Reviewed-on: https://go-review.googlesource.com/c/tools/+/472875 Reviewed-by: Alan Donovan <[email protected]> Run-TryBot: Robert Findley <[email protected]> gopls-CI: kokoro <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent 6eb432f commit fdb0da6

File tree

1 file changed

+59
-16
lines changed

1 file changed

+59
-16
lines changed

gopls/internal/regtest/bench/didchange_test.go

+59-16
Original file line numberDiff line numberDiff line change
@@ -6,41 +6,47 @@ package bench
66

77
import (
88
"fmt"
9+
"sync/atomic"
910
"testing"
11+
"time"
1012

13+
"golang.org/x/tools/gopls/internal/lsp/fake"
1114
"golang.org/x/tools/gopls/internal/lsp/protocol"
1215
)
1316

17+
// Use a global edit counter as bench function may execute multiple times, and
18+
// we want to avoid cache hits. Use time.Now to also avoid cache hits from the
19+
// shared file cache.
20+
var editID int64 = time.Now().UnixNano()
21+
22+
var didChangeTests = []struct {
23+
repo string
24+
file string
25+
}{
26+
{"istio", "pkg/fuzz/util.go"},
27+
{"kubernetes", "pkg/controller/lookup_cache.go"},
28+
{"kuma", "api/generic/insights.go"},
29+
{"pkgsite", "internal/frontend/server.go"},
30+
{"starlark", "starlark/eval.go"},
31+
{"tools", "internal/lsp/cache/snapshot.go"},
32+
}
33+
1434
// BenchmarkDidChange benchmarks modifications of a single file by making
1535
// synthetic modifications in a comment. It controls pacing by waiting for the
1636
// server to actually start processing the didChange notification before
1737
// proceeding. Notably it does not wait for diagnostics to complete.
1838
func BenchmarkDidChange(b *testing.B) {
19-
tests := []struct {
20-
repo string
21-
file string
22-
}{
23-
{"istio", "pkg/fuzz/util.go"},
24-
{"kubernetes", "pkg/controller/lookup_cache.go"},
25-
{"kuma", "api/generic/insights.go"},
26-
{"pkgsite", "internal/frontend/server.go"},
27-
{"starlark", "starlark/eval.go"},
28-
{"tools", "internal/lsp/cache/snapshot.go"},
29-
}
30-
31-
for _, test := range tests {
32-
edits := 0 // bench function may execute multiple times
39+
for _, test := range didChangeTests {
3340
b.Run(test.repo, func(b *testing.B) {
3441
env := getRepo(b, test.repo).sharedEnv(b)
3542
env.OpenFile(test.file)
36-
env.AfterChange()
3743
// Insert the text we'll be modifying at the top of the file.
3844
env.EditBuffer(test.file, protocol.TextEdit{NewText: "// __REGTEST_PLACEHOLDER_0__\n"})
3945
env.AfterChange()
4046
b.ResetTimer()
4147

4248
for i := 0; i < b.N; i++ {
43-
edits++
49+
edits := atomic.AddInt64(&editID, 1)
4450
env.EditBuffer(test.file, protocol.TextEdit{
4551
Range: protocol.Range{
4652
Start: protocol.Position{Line: 0, Character: 0},
@@ -54,3 +60,40 @@ func BenchmarkDidChange(b *testing.B) {
5460
})
5561
}
5662
}
63+
64+
func BenchmarkDiagnoseChange(b *testing.B) {
65+
for _, test := range didChangeTests {
66+
b.Run(test.repo, func(b *testing.B) {
67+
// Use a new env to avoid the diagnostic delay: we want to measure how
68+
// long it takes to produce the diagnostics.
69+
env := repos[test.repo].newEnv(b, "diagnoseChange", fake.EditorConfig{
70+
Settings: map[string]interface{}{
71+
"diagnosticsDelay": "0s",
72+
},
73+
})
74+
env.OpenFile(test.file)
75+
// Insert the text we'll be modifying at the top of the file.
76+
env.EditBuffer(test.file, protocol.TextEdit{NewText: "// __REGTEST_PLACEHOLDER_0__\n"})
77+
env.AfterChange()
78+
b.ResetTimer()
79+
80+
// We must use an extra subtest layer here, so that we only set up the
81+
// shared env once (otherwise we pay additional overhead and the profiling
82+
// flags don't work).
83+
b.Run("diagnose", func(b *testing.B) {
84+
for i := 0; i < b.N; i++ {
85+
edits := atomic.AddInt64(&editID, 1)
86+
env.EditBuffer(test.file, protocol.TextEdit{
87+
Range: protocol.Range{
88+
Start: protocol.Position{Line: 0, Character: 0},
89+
End: protocol.Position{Line: 1, Character: 0},
90+
},
91+
// Increment the placeholder text, to ensure cache misses.
92+
NewText: fmt.Sprintf("// __REGTEST_PLACEHOLDER_%d__\n", edits),
93+
})
94+
env.AfterChange()
95+
}
96+
})
97+
})
98+
}
99+
}

0 commit comments

Comments
 (0)