rate: avoid creating timer in WaitN if delay is zero
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 <bradfitz@golang.org>
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 @@
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 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)
+ }
+}