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.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Description
defermust 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
defermechanism 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