浏览代码

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>
Bob Potter 7 年之前
父节点
当前提交
fbb02b2291
共有 2 个文件被更改,包括 16 次插入2 次删除
  1. 6 2
      rate/rate.go
  2. 10 0
      rate/rate_test.go

+ 6 - 2
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:

+ 10 - 0
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)
+	}
+}