Skip to content

Commit

Permalink
rate: double reserveN perf by 2x
Browse files Browse the repository at this point in the history
This commit increase the speed of reserveN by 2x by removing the defer
to unlock.

NOTE: I did an audit of the code between Lock and Unlock and did not see
anything that can panic causing the Unlock to averted.

benchmark             old ns/op     new ns/op     delta
BenchmarkAllowN-4     290           143           -50.69%

benchmark             old allocs     new allocs     delta
BenchmarkAllowN-4     0              0              +0.00%

benchmark             old bytes     new bytes     delta
BenchmarkAllowN-4     0             0             +0.00%

Change-Id: I01c23f4998f5451ea8efedd02e744fb5a74eae0d
Reviewed-on: https://go-review.googlesource.com/29379
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
  • Loading branch information
bmizerany authored and bradfitz committed Sep 19, 2016
1 parent a4bde12 commit 2bc1b4f
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 1 deletion.
3 changes: 2 additions & 1 deletion rate/rate.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,9 +281,9 @@ func (lim *Limiter) SetLimitAt(now time.Time, newLimit Limit) {
// reserveN returns Reservation, not *Reservation, to avoid allocation in AllowN and WaitN.
func (lim *Limiter) reserveN(now time.Time, n int, maxFutureReserve time.Duration) Reservation {
lim.mu.Lock()
defer lim.mu.Unlock()

if lim.limit == Inf {
lim.mu.Unlock()
return Reservation{
ok: true,
lim: lim,
Expand Down Expand Up @@ -326,6 +326,7 @@ func (lim *Limiter) reserveN(now time.Time, n int, maxFutureReserve time.Duratio
lim.last = last
}

lim.mu.Unlock()
return r
}

Expand Down
12 changes: 12 additions & 0 deletions rate/rate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,3 +425,15 @@ func TestWaitTimeout(t *testing.T) {
runWait(t, lim, wait{"act-now", ctx, 2, 0, true})
runWait(t, lim, wait{"w-timeout-err", ctx, 3, 0, false})
}

func BenchmarkAllowN(b *testing.B) {
lim := NewLimiter(Every(1*time.Second), 1)
now := time.Now()
b.ReportAllocs()
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
lim.AllowN(now, 1)
}
})
}

0 comments on commit 2bc1b4f

Please sign in to comment.