]> Cypherpunks repositories - gostls13.git/commitdiff
time: clean up benchmarks
authorRuss Cox <rsc@golang.org>
Mon, 11 Mar 2024 03:41:33 +0000 (23:41 -0400)
committerGopher Robot <gobot@golang.org>
Wed, 13 Mar 2024 20:57:28 +0000 (20:57 +0000)
Comparing BenchmarkStop against very old commits like
CL 13094043, I was very confused about how timers had
gotten almost 10X slower since 2013.

It turns out that CL 68060043 introduced a factor of 1000
in the benchmark cost, by counting batches of 1000 as 1 op
instead of 1000 ops, and timers have actually gotten
dramatically faster since 2013, with the addition of per-P
timer heaps and other optimizations.

This CL rewrites the benchmarks to use testing.PB directly,
so that the factor of 1000 disappears, and "/op" really means "/op".
In the few tests that need to run in batches for one reason or
another, add "1000" to the name to make clear that batches
are being run.

Change-Id: I27ed74d1e420934982e4205aad4f218cdfc42509
Reviewed-on: https://go-review.googlesource.com/c/go/+/570495
Auto-Submit: Russ Cox <rsc@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/time/sleep_test.go
src/time/tick_test.go

index 7bad49f41324bb776cabdc58476c8a0c1a6efd51..b50f9cd5a5a3fe84142e0236a5c71e00dac7686d 100644 (file)
@@ -148,8 +148,7 @@ func TestAfterFuncStarvation(t *testing.T) {
        wg.Wait()
 }
 
-func benchmark(b *testing.B, bench func(n int)) {
-
+func benchmark(b *testing.B, bench func(*testing.PB)) {
        // Create equal number of garbage timers on each P before starting
        // the benchmark.
        var wg sync.WaitGroup
@@ -168,11 +167,7 @@ func benchmark(b *testing.B, bench func(n int)) {
        wg.Wait()
 
        b.ResetTimer()
-       b.RunParallel(func(pb *testing.PB) {
-               for pb.Next() {
-                       bench(1000)
-               }
-       })
+       b.RunParallel(bench)
        b.StopTimer()
 
        for _, garbage := range garbageAll {
@@ -182,27 +177,29 @@ func benchmark(b *testing.B, bench func(n int)) {
        }
 }
 
-func BenchmarkAfterFunc(b *testing.B) {
-       benchmark(b, func(n int) {
-               c := make(chan bool)
-               var f func()
-               f = func() {
-                       n--
-                       if n >= 0 {
-                               AfterFunc(0, f)
-                       } else {
-                               c <- true
+func BenchmarkAfterFunc1000(b *testing.B) {
+       benchmark(b, func(pb *testing.PB) {
+               for pb.Next() {
+                       n := 1000
+                       c := make(chan bool)
+                       var f func()
+                       f = func() {
+                               n--
+                               if n >= 0 {
+                                       AfterFunc(0, f)
+                               } else {
+                                       c <- true
+                               }
                        }
+                       AfterFunc(0, f)
+                       <-c
                }
-
-               AfterFunc(0, f)
-               <-c
        })
 }
 
 func BenchmarkAfter(b *testing.B) {
-       benchmark(b, func(n int) {
-               for i := 0; i < n; i++ {
+       benchmark(b, func(pb *testing.PB) {
+               for pb.Next() {
                        <-After(1)
                }
        })
@@ -210,59 +207,65 @@ func BenchmarkAfter(b *testing.B) {
 
 func BenchmarkStop(b *testing.B) {
        b.Run("impl=chan", func(b *testing.B) {
-               benchmark(b, func(n int) {
-                       for i := 0; i < n; i++ {
+               benchmark(b, func(pb *testing.PB) {
+                       for pb.Next() {
                                NewTimer(1 * Second).Stop()
                        }
                })
        })
        b.Run("impl=func", func(b *testing.B) {
-               benchmark(b, func(n int) {
-                       for i := 0; i < n; i++ {
+               benchmark(b, func(pb *testing.PB) {
+                       for pb.Next() {
                                newTimerFunc(1 * Second).Stop()
                        }
                })
        })
 }
 
-func BenchmarkSimultaneousAfterFunc(b *testing.B) {
-       benchmark(b, func(n int) {
-               var wg sync.WaitGroup
-               wg.Add(n)
-               for i := 0; i < n; i++ {
-                       AfterFunc(0, wg.Done)
+func BenchmarkSimultaneousAfterFunc1000(b *testing.B) {
+       benchmark(b, func(pb *testing.PB) {
+               for pb.Next() {
+                       n := 1000
+                       var wg sync.WaitGroup
+                       wg.Add(n)
+                       for range n {
+                               AfterFunc(0, wg.Done)
+                       }
+                       wg.Wait()
                }
-               wg.Wait()
        })
 }
 
-func BenchmarkStartStop(b *testing.B) {
-       benchmark(b, func(n int) {
-               timers := make([]*Timer, n)
-               for i := 0; i < n; i++ {
-                       timers[i] = AfterFunc(Hour, nil)
-               }
+func BenchmarkStartStop1000(b *testing.B) {
+       benchmark(b, func(pb *testing.PB) {
+               for pb.Next() {
+                       const N = 1000
+                       timers := make([]*Timer, N)
+                       for i := range timers {
+                               timers[i] = AfterFunc(Hour, nil)
+                       }
 
-               for i := 0; i < n; i++ {
-                       timers[i].Stop()
+                       for i := range timers {
+                               timers[i].Stop()
+                       }
                }
        })
 }
 
 func BenchmarkReset(b *testing.B) {
        b.Run("impl=chan", func(b *testing.B) {
-               benchmark(b, func(n int) {
+               benchmark(b, func(pb *testing.PB) {
                        t := NewTimer(Hour)
-                       for i := 0; i < n; i++ {
+                       for pb.Next() {
                                t.Reset(Hour)
                        }
                        t.Stop()
                })
        })
        b.Run("impl=func", func(b *testing.B) {
-               benchmark(b, func(n int) {
+               benchmark(b, func(pb *testing.PB) {
                        t := newTimerFunc(Hour)
-                       for i := 0; i < n; i++ {
+                       for pb.Next() {
                                t.Reset(Hour)
                        }
                        t.Stop()
@@ -270,17 +273,20 @@ func BenchmarkReset(b *testing.B) {
        })
 }
 
-func BenchmarkSleep(b *testing.B) {
-       benchmark(b, func(n int) {
-               var wg sync.WaitGroup
-               wg.Add(n)
-               for i := 0; i < n; i++ {
-                       go func() {
-                               Sleep(Nanosecond)
-                               wg.Done()
-                       }()
+func BenchmarkSleep1000(b *testing.B) {
+       benchmark(b, func(pb *testing.PB) {
+               for pb.Next() {
+                       const N = 1000
+                       var wg sync.WaitGroup
+                       wg.Add(N)
+                       for range N {
+                               go func() {
+                                       Sleep(Nanosecond)
+                                       wg.Done()
+                               }()
+                       }
+                       wg.Wait()
                }
-               wg.Wait()
        })
 }
 
index a2c6b24861bb874155cffcd69bf2feb58e6f7130..0ba0c361728b0bc3b40ac79f63d45bb831d5daf0 100644 (file)
@@ -227,9 +227,9 @@ func TestLongAdjustTimers(t *testing.T) {
        }
 }
 func BenchmarkTicker(b *testing.B) {
-       benchmark(b, func(n int) {
+       benchmark(b, func(pb *testing.PB) {
                ticker := NewTicker(Nanosecond)
-               for i := 0; i < n; i++ {
+               for pb.Next() {
                        <-ticker.C
                }
                ticker.Stop()
@@ -237,9 +237,9 @@ func BenchmarkTicker(b *testing.B) {
 }
 
 func BenchmarkTickerReset(b *testing.B) {
-       benchmark(b, func(n int) {
+       benchmark(b, func(pb *testing.PB) {
                ticker := NewTicker(Nanosecond)
-               for i := 0; i < n; i++ {
+               for pb.Next() {
                        ticker.Reset(Nanosecond * 2)
                }
                ticker.Stop()
@@ -247,9 +247,9 @@ func BenchmarkTickerReset(b *testing.B) {
 }
 
 func BenchmarkTickerResetNaive(b *testing.B) {
-       benchmark(b, func(n int) {
+       benchmark(b, func(pb *testing.PB) {
                ticker := NewTicker(Nanosecond)
-               for i := 0; i < n; i++ {
+               for pb.Next() {
                        ticker.Stop()
                        ticker = NewTicker(Nanosecond * 2)
                }