1// Copyright 2014 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package context_test 6 7import ( 8 . "context" 9 "fmt" 10 "runtime" 11 "sync" 12 "testing" 13 "time" 14) 15 16func BenchmarkCommonParentCancel(b *testing.B) { 17 root := WithValue(Background(), "key", "value") 18 shared, sharedcancel := WithCancel(root) 19 defer sharedcancel() 20 21 b.ResetTimer() 22 b.RunParallel(func(pb *testing.PB) { 23 x := 0 24 for pb.Next() { 25 ctx, cancel := WithCancel(shared) 26 if ctx.Value("key").(string) != "value" { 27 b.Fatal("should not be reached") 28 } 29 for i := 0; i < 100; i++ { 30 x /= x + 1 31 } 32 cancel() 33 for i := 0; i < 100; i++ { 34 x /= x + 1 35 } 36 } 37 }) 38} 39 40func BenchmarkWithTimeout(b *testing.B) { 41 for concurrency := 40; concurrency <= 4e5; concurrency *= 100 { 42 name := fmt.Sprintf("concurrency=%d", concurrency) 43 b.Run(name, func(b *testing.B) { 44 benchmarkWithTimeout(b, concurrency) 45 }) 46 } 47} 48 49func benchmarkWithTimeout(b *testing.B, concurrentContexts int) { 50 gomaxprocs := runtime.GOMAXPROCS(0) 51 perPContexts := concurrentContexts / gomaxprocs 52 root := Background() 53 54 // Generate concurrent contexts. 55 var wg sync.WaitGroup 56 ccf := make([][]CancelFunc, gomaxprocs) 57 for i := range ccf { 58 wg.Add(1) 59 go func(i int) { 60 defer wg.Done() 61 cf := make([]CancelFunc, perPContexts) 62 for j := range cf { 63 _, cf[j] = WithTimeout(root, time.Hour) 64 } 65 ccf[i] = cf 66 }(i) 67 } 68 wg.Wait() 69 70 b.ResetTimer() 71 b.RunParallel(func(pb *testing.PB) { 72 wcf := make([]CancelFunc, 10) 73 for pb.Next() { 74 for i := range wcf { 75 _, wcf[i] = WithTimeout(root, time.Hour) 76 } 77 for _, f := range wcf { 78 f() 79 } 80 } 81 }) 82 b.StopTimer() 83 84 for _, cf := range ccf { 85 for _, f := range cf { 86 f() 87 } 88 } 89} 90 91func BenchmarkCancelTree(b *testing.B) { 92 depths := []int{1, 10, 100, 1000} 93 for _, d := range depths { 94 b.Run(fmt.Sprintf("depth=%d", d), func(b *testing.B) { 95 b.Run("Root=Background", func(b *testing.B) { 96 for i := 0; i < b.N; i++ { 97 buildContextTree(Background(), d) 98 } 99 }) 100 b.Run("Root=OpenCanceler", func(b *testing.B) { 101 for i := 0; i < b.N; i++ { 102 ctx, cancel := WithCancel(Background()) 103 buildContextTree(ctx, d) 104 cancel() 105 } 106 }) 107 b.Run("Root=ClosedCanceler", func(b *testing.B) { 108 for i := 0; i < b.N; i++ { 109 ctx, cancel := WithCancel(Background()) 110 cancel() 111 buildContextTree(ctx, d) 112 } 113 }) 114 }) 115 } 116} 117 118func buildContextTree(root Context, depth int) { 119 for d := 0; d < depth; d++ { 120 root, _ = WithCancel(root) 121 } 122} 123 124func BenchmarkCheckCanceled(b *testing.B) { 125 ctx, cancel := WithCancel(Background()) 126 cancel() 127 b.Run("Err", func(b *testing.B) { 128 for i := 0; i < b.N; i++ { 129 ctx.Err() 130 } 131 }) 132 b.Run("Done", func(b *testing.B) { 133 for i := 0; i < b.N; i++ { 134 select { 135 case <-ctx.Done(): 136 default: 137 } 138 } 139 }) 140} 141 142func BenchmarkContextCancelDone(b *testing.B) { 143 ctx, cancel := WithCancel(Background()) 144 defer cancel() 145 146 b.RunParallel(func(pb *testing.PB) { 147 for pb.Next() { 148 select { 149 case <-ctx.Done(): 150 default: 151 } 152 } 153 }) 154} 155 156func BenchmarkDeepValueNewGoRoutine(b *testing.B) { 157 for _, depth := range []int{10, 20, 30, 50, 100} { 158 ctx := Background() 159 for i := 0; i < depth; i++ { 160 ctx = WithValue(ctx, i, i) 161 } 162 163 b.Run(fmt.Sprintf("depth=%d", depth), func(b *testing.B) { 164 for i := 0; i < b.N; i++ { 165 var wg sync.WaitGroup 166 wg.Add(1) 167 go func() { 168 defer wg.Done() 169 ctx.Value(-1) 170 }() 171 wg.Wait() 172 } 173 }) 174 } 175} 176 177func BenchmarkDeepValueSameGoRoutine(b *testing.B) { 178 for _, depth := range []int{10, 20, 30, 50, 100} { 179 ctx := Background() 180 for i := 0; i < depth; i++ { 181 ctx = WithValue(ctx, i, i) 182 } 183 184 b.Run(fmt.Sprintf("depth=%d", depth), func(b *testing.B) { 185 for i := 0; i < b.N; i++ { 186 ctx.Value(-1) 187 } 188 }) 189 } 190} 191