Go EP14: Heap-allocated Defer, Stack-allocated Defer, Open-coded Defer
The defer statement in Go actually comes in three flavors: open-coded, heap-allocated, and stack-allocated. Each has its own performance quirks and use cases.
In this week, I’ll be sharing key takeaways and highlights from my recent articles: Defer in Go: From Basic to Traps.
If you're interested in diving deeper into the content, you can follow the links provided to read the full posts.
The
defer
statement in Go actually comes in three flavors: open-coded, heap-allocated, and stack-allocated. Each has its own performance quirks and use cases. This could be pretty important if you’re trying to squeeze out every bit of performance in your Go programs.Deferred functions in Go run in a last-in, first-out order. Basically, the last one you defer is the first one that gets executed. This is managed using a linked list within each goroutine, which makes it quite efficient to handle multiple
defer
calls across different functions.When you use
defer
in Go, the arguments and receiver for the deferred function are evaluated right away when thedefer
statement is executed, not when the function actually runs.If you’re using
recover
to handle panics, it’s important to call it directly within a deferred function. So, if you try to userecover
in other ways, like as a deferred function itself or within a nested function, it won’t catch panics as you’d expect.Go has an optimization called open-coded defers, where
defer
calls are inlined directly at the end of a function and just before every return statement in the assembly code. But this optimization only kicks in under certain scenarios, like a limit on the number of defers and return statements, and the function can’t have heap-allocated defers.