From fbb02b2291d28baffd63558aa44b4b56f178d650 Mon Sep 17 00:00:00 2001 From: Bob Potter Date: Thu, 12 Apr 2018 16:56:04 +0000 Subject: [PATCH] rate: avoid creating timer in WaitN if delay is zero MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit name old time/op new time/op delta AllowN-4 76.7ns ± 6% 76.6ns ± 3% ~ (p=0.897 n=10+10) WaitNNoDelay-4 1.36µs ± 3% 0.10µs ± 1% -92.64% (p=0.000 n=10+9) name old alloc/op new alloc/op delta AllowN-4 0.00B 0.00B ~ (all equal) WaitNNoDelay-4 208B ± 0% 0B -100.00% (p=0.000 n=10+10) name old allocs/op new allocs/op delta AllowN-4 0.00 0.00 ~ (all equal) WaitNNoDelay-4 3.00 ± 0% 0.00 -100.00% (p=0.000 n=10+10) Change-Id: I83addc3b3f7b053d6eee637fe188e21ca9b39f11 GitHub-Last-Rev: 2284b8e7b14d2f54870ddb80a40e8cf24996cd1f GitHub-Pull-Request: golang/time#5 Reviewed-on: https://go-review.googlesource.com/106461 Reviewed-by: Brad Fitzpatrick --- rate/rate.go | 8 ++++++-- rate/rate_test.go | 10 ++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/rate/rate.go b/rate/rate.go index eabcd11..7228d97 100644 --- a/rate/rate.go +++ b/rate/rate.go @@ -253,8 +253,12 @@ func (lim *Limiter) waitN(ctx contextContext, n int) (err error) { if !r.ok { return fmt.Errorf("rate: Wait(n=%d) would exceed context deadline", n) } - // Wait - t := time.NewTimer(r.DelayFrom(now)) + // Wait if necessary + delay := r.DelayFrom(now) + if delay == 0 { + return nil + } + t := time.NewTimer(delay) defer t.Stop() select { case <-t.C: diff --git a/rate/rate_test.go b/rate/rate_test.go index e8add69..ec8c66d 100644 --- a/rate/rate_test.go +++ b/rate/rate_test.go @@ -447,3 +447,13 @@ func BenchmarkAllowN(b *testing.B) { } }) } + +func BenchmarkWaitNNoDelay(b *testing.B) { + lim := NewLimiter(Limit(b.N), b.N) + ctx := context.Background() + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + lim.WaitN(ctx, 1) + } +}