rate: double reserveN perf by 2x
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>
diff --git a/rate/rate.go b/rate/rate.go
index 2131b92..26ed8b3 100644
--- a/rate/rate.go
+++ b/rate/rate.go
@@ -281,9 +281,9 @@
// 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,
@@ -326,6 +326,7 @@
lim.last = last
}
+ lim.mu.Unlock()
return r
}
diff --git a/rate/rate_test.go b/rate/rate_test.go
index cd152a5..a7c0285 100644
--- a/rate/rate_test.go
+++ b/rate/rate_test.go
@@ -425,3 +425,15 @@
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)
+ }
+ })
+}