Unfortunately, I made a mistake while writing benchmarks for jub0bs/fcors. A mistake that ultimately fooled me into thinking that invocations of the CORS middleware it provides (almost) never incur heap allocations... but they do. Not a prohibitive amount, but still. 😞​

I was reusing the same http.ResponseRecorder across iterations of the benchmark loop, but making sure to clear its Header field during each iteration (because my middleware adds HTTP headers to the response). Of course, however, the new clear builtin leaves the capacity of the http.Header unchanged.

The call to ServeHTTP in the first iteration of the benchmark loop would grow the map as needed and, therefore, calls to ServeHTTP in subsequent iterations wouldn't incur any allocations.

I was deceived by the benchmark results, in which the allocations (only incurred during the first iteration) would get averaged out to zero. 😬​

I only realised my mistake after running the benchmark with -benchtime 1x.

Unfortunately, unless there is progress on https://github.com/golang/go/issues/56182, I don't think I can get rid of those heap allocations.

#golang

runtime: expand capacity of map by more than 1 at a time? · Issue #56182 · golang/go

Follow-on to #52157 and #54454 Right now the reference code in /x/exp/maps.Copy will potentially call runtime.growWork_faststr and runtime.hashGrow many times if src and dst are mostly disjoint and...

GitHub