From 54827d47eed8f943f26fa989b963ce6126ccb873 Mon Sep 17 00:00:00 2001 From: lorneli Date: Fri, 27 Apr 2018 00:16:58 +0800 Subject: [PATCH] pkg/idutil: use count field as atomic variable Use atomic.AddUint64 instead of mutex lock to inc count field. Bench result: benchmark old ns/op new ns/op delta BenchmarkNext-4 163 26.3 -83.87% --- pkg/idutil/id.go | 9 +++------ pkg/idutil/id_test.go | 9 +++++++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/pkg/idutil/id.go b/pkg/idutil/id.go index 2da210626..63a02cd73 100644 --- a/pkg/idutil/id.go +++ b/pkg/idutil/id.go @@ -18,7 +18,7 @@ package idutil import ( "math" - "sync" + "sync/atomic" "time" ) @@ -47,7 +47,6 @@ const ( // id generated after restart is unique because etcd throughput is << // 256req/ms(250k reqs/second). type Generator struct { - mu sync.Mutex // high order 2 bytes prefix uint64 // low order 6 bytes @@ -66,10 +65,8 @@ func NewGenerator(memberID uint16, now time.Time) *Generator { // Next generates a id that is unique. func (g *Generator) Next() uint64 { - g.mu.Lock() - defer g.mu.Unlock() - g.suffix++ - id := g.prefix | lowbit(g.suffix, suffixLen) + suffix := atomic.AddUint64(&g.suffix, 1) + id := g.prefix | lowbit(suffix, suffixLen) return id } diff --git a/pkg/idutil/id_test.go b/pkg/idutil/id_test.go index ddcbc6d34..92be7fb35 100644 --- a/pkg/idutil/id_test.go +++ b/pkg/idutil/id_test.go @@ -53,3 +53,12 @@ func TestNext(t *testing.T) { } } } + +func BenchmarkNext(b *testing.B) { + g := NewGenerator(0x12, time.Now()) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + g.Next() + } +}