Skip to content

Commit

Permalink
pkg/idutil: use count field as atomic variable
Browse files Browse the repository at this point in the history
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%
  • Loading branch information
lorneli committed Apr 26, 2018
1 parent afef4a5 commit 54827d4
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 6 deletions.
9 changes: 3 additions & 6 deletions pkg/idutil/id.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ package idutil

import (
"math"
"sync"
"sync/atomic"
"time"
)

Expand Down Expand Up @@ -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
Expand All @@ -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
}

Expand Down
9 changes: 9 additions & 0 deletions pkg/idutil/id_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
}

0 comments on commit 54827d4

Please sign in to comment.