Improvement: Too much defer
usage
#543
Replies: 1 comment 7 replies
-
We usually use I understand that encapsulating a shared and guarded variable within the lock, could result in a shorter lock time, but it comes with some costs. func (g *guardedClass) DoSomething() {
g.lk.Lock()
defer g.lk.Unlock()
g.foo()
g.noNeedGuard()
g.bar()
}
func (g *guardedClass) DoSomething() {
g.lk.RLock()
g.foo()
g.lk.RUnlock()
g.noNeedGuard()
g.lk.RLock()
g.bar()
g.lk.RUnlock()
} There are a few considerations about the second example:
If the To sum up: the question is, how much should be the scope of a lock? Should it be the entire function scope or limited to the guarded variables? It seems that for most cases the first approach (example 1) is a good choice. |
Beta Was this translation helpful? Give feedback.
-
Description
defer
must use just when we are not sure a bad thing (caused by used panic() in other places!) may occur in a process(goroutine).How to solve
easily find and replace all defer with simple flow! e.g. Fix state.state.Genesis() to this version:
EDIT: Read deeply about
defer
mechanism heredefer and reflection calls can build frames in the heap with the appropriate heap bitmap. The call bridge in these cases must open a new stack frame, copy stack to the stack, load the register arguments, call pc, and then copy the register results and the stack results back to the in-heap frame (using write barriers where necessary). It may be valuable to have optimized versions of this bridge for tail-calls (always the case for defer) and register-only calls (likely a common case). In the register-only reflection call case, the bridge could take the register arguments as arguments itself and return register results as results; this would avoid any copying or write barriers.
Beta Was this translation helpful? Give feedback.
All reactions