|
|
|
|
|
by e12e
2310 days ago
|
|
> This release improves the performance of most uses of defer to incur almost zero overhead compared to calling the deferred function directly. Anyone happen to know why there used to be overhead here/what changed? From my comfortable sofa, it seems that there should be little difference between a defer-ed and direct call? |
|
The full design doc is here: https://github.com/golang/proposal/blob/master/design/34481-...
> Go 1.13 implements the defer statement by calling into the runtime to push a "defer object" onto the defer chain. Then, in any function that contains defer statements, the compiler inserts a call to runtime.deferreturn at every function exit point to unwind that function's defers.
> We propose optimizing deferred calls in functions where every defer is executed at most once (specifically, a defer may be on a conditional path, but is never in a loop in the control-flow graph). In this optimization, the compiler assigns a bit for every defer site to indicate whether that defer had been reached or not. The defer statement itself simply sets the corresponding bit and stores all necessary arguments in specific stack slots. Then, at every exit point of the function, the compiler open-codes each deferred call, protected by (and clearing) each corresponding bit.