Closed adonovan closed 1 year ago
doing it at variable intervals
FWIW, I still think it would be nice to gate the rate of cache cleaning based on the rate of cache creation.
(For example, the cleaner goroutine could do one pass at startup and then block until some operation creates a new file in the cache, at which point it could then unblock for another pass.)
Change https://go.dev/cl/506815 mentions this issue: gopls/internal/lsp/filecache: reduce GC frequency
Change https://go.dev/cl/506816 mentions this issue: gopls/internal/lsp/filecache: increase idle GC period to 6 hours
gopls v0.12 uses too much CPU while idle: approximately 15% of a core on average, according to both top(1) and pprof (although the latter is unreliable due to a macOS kernel bug in setitimer). Based on the profile, it appears to be because the filecache gc calls
filepath.Walk
every minute. On my machine, with a cache of 20,000 directories and 355,000 files, it takes /usr/bin/find 1.7s of CPU to produce 44MB of filenames, and filepath.Walk probably costs some multiple of this.We should reduce the cost of gc by some combination of (a) doing it less often, especially since there's no longer any need to try to keep with the high rate of garbage production in tests. (b) doing it at variable intervals, using some kind of backoff scheme if little was collected. (c) doing it more efficiently, either by allocating less memory and fewer stat objects than filepath.Walk. (d) doing it more intelligently, by building a stateful representation of the directory tree and only doing the I/O necessary to update it incrementally. (e) doing it in proportion to the rate of garbage creation (e.g. using a leaky bucket fed by calls to Set).
@bcmills