Skip to content

Commit de54582

Browse files
committed
gopls/internal/lsp/filecache: process batches of stats before sleeping
Sleeping after every stat during GC introduces noticeable overhead on my computer. Process stats in batches of 1000 to mitigate this overhead. Change-Id: I039c2d2f10d1d3d44f3a7ac77e23f8f4c0892d5c Reviewed-on: https://go-review.googlesource.com/c/tools/+/472180 TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Alan Donovan <[email protected]> gopls-CI: kokoro <[email protected]> Run-TryBot: Robert Findley <[email protected]>
1 parent bc2e2c2 commit de54582

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

gopls/internal/lsp/filecache/filecache.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,17 @@ func hashExecutable() (hash [32]byte, err error) {
234234
// process, possibly running a different version of gopls, possibly
235235
// running concurrently.
236236
func gc(goplsDir string) {
237-
const period = 1 * time.Minute // period between collections
238-
const statDelay = 100 * time.Microsecond // delay between stats to smooth out I/O
237+
const period = 1 * time.Minute // period between collections
238+
// Sleep statDelay*batchSize between stats to smooth out I/O.
239+
//
240+
// The constants below were chosen using the following heuristics:
241+
// - 1GB of filecache is on the order of ~100-200k files, in which case
242+
// 100μs delay per file introduces 10-20s of additional walk time, less
243+
// than the 1m gc period.
244+
// - Processing batches of stats at once is much more efficient than
245+
// sleeping after every stat (due to OS optimizations).
246+
const statDelay = 100 * time.Microsecond // average delay between stats, to smooth out I/O
247+
const batchSize = 1000 // # of stats to process before sleeping
239248
const maxAge = 5 * 24 * time.Hour // max time since last access before file is deleted
240249

241250
// The macOS filesystem is strikingly slow, at least on some machines.
@@ -261,6 +270,7 @@ func gc(goplsDir string) {
261270
stat os.FileInfo
262271
}
263272
var files []item
273+
start := time.Now()
264274
var total int64 // bytes
265275
_ = filepath.Walk(goplsDir, func(path string, stat os.FileInfo, err error) error {
266276
if err != nil {
@@ -285,7 +295,12 @@ func gc(goplsDir string) {
285295
} else {
286296
files = append(files, item{path, stat})
287297
total += stat.Size()
288-
time.Sleep(statDelay)
298+
if debug && len(files)%1000 == 0 {
299+
log.Printf("filecache: checked %d files in %v", len(files), time.Since(start))
300+
}
301+
if len(files)%batchSize == 0 {
302+
time.Sleep(batchSize * statDelay)
303+
}
289304
}
290305
}
291306
return nil

0 commit comments

Comments
 (0)