aboutsummaryrefslogtreecommitdiff
path: root/src/expvar
diff options
context:
space:
mode:
authorEvan Phoenix <evan@phx.io>2015-01-28 09:16:44 -0800
committerDmitry Vyukov <dvyukov@google.com>2015-01-29 08:24:00 +0000
commitbd043d862962ec844994a658d8b4f8ab89b6d80e (patch)
tree95803d98c48c25f1948638a80c9788e261adfdbc /src/expvar
parentb49c3ac2d50c1aed28bc55b09415ad8d861237e9 (diff)
downloadgo-bd043d862962ec844994a658d8b4f8ab89b6d80e.tar.gz
go-bd043d862962ec844994a658d8b4f8ab89b6d80e.zip
expvar: Use sync/atomic to manipulate Int for better perf
Using a mutex to protect a single int operation is quite heavyweight. Using sync/atomic provides much better performance. This change was benchmarked as such: BenchmarkSync 10000000 139 ns/op BenchmarkAtomic 200000000 9.90 ns/op package blah import ( "sync" "sync/atomic" "testing" ) type Int struct { mu sync.RWMutex i int64 } func (v *Int) Add(delta int64) { v.mu.Lock() defer v.mu.Unlock() v.i += delta } type AtomicInt struct { i int64 } func (v *AtomicInt) Add(delta int64) { atomic.AddInt64(&v.i, delta) } func BenchmarkSync(b *testing.B) { s := new(Int) for i := 0; i < b.N; i++ { s.Add(1) } } func BenchmarkAtomic(b *testing.B) { s := new(AtomicInt) for i := 0; i < b.N; i++ { s.Add(1) } } Change-Id: I6998239c785967647351bbfe8533c38e4894543b Reviewed-on: https://go-review.googlesource.com/3430 Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
Diffstat (limited to 'src/expvar')
-rw-r--r--src/expvar/expvar.go16
1 files changed, 5 insertions, 11 deletions
diff --git a/src/expvar/expvar.go b/src/expvar/expvar.go
index 9b6dab487c..2cb515a678 100644
--- a/src/expvar/expvar.go
+++ b/src/expvar/expvar.go
@@ -32,6 +32,7 @@ import (
"sort"
"strconv"
"sync"
+ "sync/atomic"
)
// Var is an abstract type for all exported variables.
@@ -41,26 +42,19 @@ type Var interface {
// Int is a 64-bit integer variable that satisfies the Var interface.
type Int struct {
- mu sync.RWMutex
- i int64
+ i int64
}
func (v *Int) String() string {
- v.mu.RLock()
- defer v.mu.RUnlock()
- return strconv.FormatInt(v.i, 10)
+ return strconv.FormatInt(atomic.LoadInt64(&v.i), 10)
}
func (v *Int) Add(delta int64) {
- v.mu.Lock()
- defer v.mu.Unlock()
- v.i += delta
+ atomic.AddInt64(&v.i, delta)
}
func (v *Int) Set(value int64) {
- v.mu.Lock()
- defer v.mu.Unlock()
- v.i = value
+ atomic.StoreInt64(&v.i, value)
}
// Float is a 64-bit float variable that satisfies the Var interface.