Reserve conversion capacity for diagnostic batches

perfloop/esbuild · ALLOCATION HOT LOOP

https://perfloop.ai/t/oss/case_85qf9fc3kr

Verdict

CLOSED · opened 2026-07-18

What happened: Closed; the settled verdict is recorded on the case.

Hypothesis

On the accepted path, formatMsgsImpl calls convertMessagesToInternal with a nil destination at api_impl.go:2196, and the helper appends one logger.Msg per supplied Message at line 831. The returned slice is then consumed only by formatMsgsImpl's immediately following rendering loop on this path. The service handler calls api.FormatMessages once for each incoming format-messages request, so this conversion runs once per request and its loop runs once per supplied diagnostic; the proposed benefit is specifically for multi-message batches, with the probe using 256 messages and production cardinality still unmeasured. A focused compiler check, `go test ./pkg/api -run '^$' -gcflags='-m=2'`, reported that the append at line 831 escapes to the heap. A scratch benchmark of this helper with 256 no-note messages measured the current nil-destination form at 32.1 us/op, 64,800 B/op, and 9 allocs/op; passing an exact-capacity destination measured 21.3 us/op, 27,264 B/op, and 1 alloc/op. That measures the conversion alone, not end-to-end formatting, whose String work may dilute the request-level gain. The removed delta is the geometric sequence of temporary logger.Msg backing-array allocations and copies per triggered batch, replaced by one exact-capacity buffer. Independently reproduce the proof through api.FormatMessages with a 1/32/256/1024-message sweep and an allocation/CPU profile; the expected signal is fewer allocations and bytes attributed to convertMessagesToInternal's outer append, with lower conversion CPU and improved request latency as batch size grows.

Change to test: Before the outer append loop, reserve enough additional logger.Msg capacity for all incoming messages when the caller-provided destination lacks it, while retaining the existing fast path for callers that already provide sufficient capacity. This makes the nil destination used by FormatMessages allocate one exact-size conversion buffer instead of repeatedly growing it.

Where it lives

perfloop/esbuild · pkg/api/api.go

Evidence

Timeline