this repo has no description

internal/core/adt: do not reuse large vertexMap maps

https://cuelang.org/cl/1226958 was a decent improvement thanks to
the reuse of vertexMap maps. However, Go is currently fairly slow
at clearing maps with large capacities, even if they have a small length
due to few entries.

For that reason, and since most maps we need are on the small side,
add a cutoff to keep most of the ~2.5% reduction in allocs
while avoiding the performance degradation due to the use of clear.

│ old │ new │
│ sec/op │ sec/op vs base │
ExportJudson 3.932 ± 1% 3.673 ± 2% -6.57% (p=0.000 n=8)

│ old │ new │
│ B/op │ B/op vs base │
ExportJudson 1.918Gi ± 0% 1.926Gi ± 0% +0.42% (p=0.000 n=8)

│ old │ new │
│ allocs/op │ allocs/op vs base │
ExportJudson 15.71M ± 0% 15.72M ± 0% +0.02% (p=0.000 n=8)

Signed-off-by: Daniel Martí <mvdan@mvdan.cc>
Change-Id: I79b3c3f39faf234e72a04c59daad7187f8772b0b
Reviewed-on: https://cue.gerrithub.io/c/cue-lang/cue/+/1226971
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@gmail.com>

+9 -1
+9 -1
internal/core/adt/overlay.go
··· 105 105 106 106 func (c *OpContext) popOverlay() { 107 107 i := len(c.overlays) - 1 108 - clear(c.overlays[i].vertexMap) 108 + // TODO(mvdan): unfortunately, clearing maps with large capacities 109 + // is fairly slow as of Go 1.25, and most uses only need few entries. 110 + // Do not reuse large maps to avoid this pitfall for now. 111 + // See: https://github.com/golang/go/issues/70617 112 + if l := len(c.overlays[i].vertexMap); l > 512 { 113 + c.overlays[i].vertexMap = nil 114 + } else { 115 + clear(c.overlays[i].vertexMap) 116 + } 109 117 c.overlays = c.overlays[:i] 110 118 } 111 119