Inlining replaces a function call with the called function’s body. Go applies it automatically when a function fits the compiler’s inlining budget, removing call overhead and enabling further optimizations. section 12.7
A common mistake is trusting a benchmark that calls a small function without using its result. After inlining, the compiler can see that the call has no side effects and eliminate it, leaving an effectively empty loop. section 11.8.3
A benchmark that measures nothing
A loop calling popcnt without storing its return value reports about 0.28 ns/op. The compiler can transform it into an empty benchmark. Store each result in a local variable, then assign the final value to a global variable after the loop; this preserves the computation while limiting per-iteration global-write overhead.
Inspect compiler decisions with go build -gcflags "-m=2". A simple sum call can become a + b, while a function exceeding the complexity budget remains uninlined. Mid-stack inlining also permits inlining functions that call other functions, supporting fast-path designs such as sync.Mutex.Lock delegating its slow path. section 12.7
var global uint64 #1
func BenchmarkPopcnt2(b *testing.B) {
var v uint64 #2
for i := 0; i < b.N; i++ {
v = popcnt(uint64(i)) #3
}
global = v #4
}
Compare local result retention with final global assignment when writing a benchmark intended to prevent optimization from erasing the work. section 11.8.3



