Use atomic.LoadUint32(&done) instead of
atomic.AddInt32(&done, 0) on fast path.
benchmark old ns/op new ns/op delta
BenchmarkOnce 13.40 7.26 -45.82%
BenchmarkOnce-2 22.90 4.04 -82.36%
BenchmarkOnce-4 25.60 2.16 -91.56%
BenchmarkOnce-8 25.80 1.38 -94.65%
BenchmarkOnce-16 24.40 1.33 -94.55%
(on HP Z600, 2 x Intel Xeon E5620, 8 HT cores, 2.4 GHz)
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/
4787041
// Once is an object that will perform exactly one action.
type Once struct {
m Mutex
- done int32
+ done uint32
}
// Do calls the function f if and only if the method is being called for the
// Do to be called, it will deadlock.
//
func (o *Once) Do(f func()) {
- if atomic.AddInt32(&o.done, 0) == 1 {
+ if atomic.LoadUint32(&o.done) == 1 {
return
}
// Slow-path.
defer o.m.Unlock()
if o.done == 0 {
f()
- atomic.CompareAndSwapInt32(&o.done, 0, 1)
+ atomic.CompareAndSwapUint32(&o.done, 0, 1)
}
}