Go Benchmark
sync.Pool Buffer Reuse
Allocating a fresh buffer every time vs reusing one from sync.Pool.
Hot paths that need a temporary bytes.Buffer or byte slice face a choice: allocate a fresh one each time and let the garbage collector clean up, or recycle buffers through sync.Pool. This benchmark writes a 1 KiB payload into a fresh buffer vs a pooled one. The allocation columns are the story: the fresh buffer allocates its backing array every single iteration (feeding the GC), while the pooled buffer allocates once, and every reuse after that is allocation-free. This is exactly how fmt, net/http, and most encoders keep their per-request allocations near zero — at the price of Reset() discipline and objects that may be dropped by the GC between uses.
1 CPU
32 CPUs
Fetches a *bytes.Buffer from a sync.Pool, calls Reset(), writes the payload, and returns it with Put. After the first iteration warms the pool, the buffer's backing array is reused and the loop runs with zero allocations. Note the obligations: always Reset() before use, never keep a reference after Put, and don't rely on the pool for correctness — the GC may empty it at any time.
Creates a fresh bytes.Buffer per iteration and writes the payload into it. Every iteration heap-allocates a new backing array (over 1 KiB here), all of which becomes garbage immediately — cheap to write, but it turns your hot path into a garbage-collector treadmill.
Contributors