diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:14:23 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:14:23 +0000 |
commit | 73df946d56c74384511a194dd01dbe099584fd1a (patch) | |
tree | fd0bcea490dd81327ddfbb31e215439672c9a068 /src/context/benchmark_test.go | |
parent | Initial commit. (diff) | |
download | golang-1.16-73df946d56c74384511a194dd01dbe099584fd1a.tar.xz golang-1.16-73df946d56c74384511a194dd01dbe099584fd1a.zip |
Adding upstream version 1.16.10.upstream/1.16.10upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/context/benchmark_test.go')
-rw-r--r-- | src/context/benchmark_test.go | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/src/context/benchmark_test.go b/src/context/benchmark_test.go new file mode 100644 index 0000000..5d56863 --- /dev/null +++ b/src/context/benchmark_test.go @@ -0,0 +1,140 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package context_test + +import ( + . "context" + "fmt" + "runtime" + "sync" + "testing" + "time" +) + +func BenchmarkCommonParentCancel(b *testing.B) { + root := WithValue(Background(), "key", "value") + shared, sharedcancel := WithCancel(root) + defer sharedcancel() + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + x := 0 + for pb.Next() { + ctx, cancel := WithCancel(shared) + if ctx.Value("key").(string) != "value" { + b.Fatal("should not be reached") + } + for i := 0; i < 100; i++ { + x /= x + 1 + } + cancel() + for i := 0; i < 100; i++ { + x /= x + 1 + } + } + }) +} + +func BenchmarkWithTimeout(b *testing.B) { + for concurrency := 40; concurrency <= 4e5; concurrency *= 100 { + name := fmt.Sprintf("concurrency=%d", concurrency) + b.Run(name, func(b *testing.B) { + benchmarkWithTimeout(b, concurrency) + }) + } +} + +func benchmarkWithTimeout(b *testing.B, concurrentContexts int) { + gomaxprocs := runtime.GOMAXPROCS(0) + perPContexts := concurrentContexts / gomaxprocs + root := Background() + + // Generate concurrent contexts. + var wg sync.WaitGroup + ccf := make([][]CancelFunc, gomaxprocs) + for i := range ccf { + wg.Add(1) + go func(i int) { + defer wg.Done() + cf := make([]CancelFunc, perPContexts) + for j := range cf { + _, cf[j] = WithTimeout(root, time.Hour) + } + ccf[i] = cf + }(i) + } + wg.Wait() + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + wcf := make([]CancelFunc, 10) + for pb.Next() { + for i := range wcf { + _, wcf[i] = WithTimeout(root, time.Hour) + } + for _, f := range wcf { + f() + } + } + }) + b.StopTimer() + + for _, cf := range ccf { + for _, f := range cf { + f() + } + } +} + +func BenchmarkCancelTree(b *testing.B) { + depths := []int{1, 10, 100, 1000} + for _, d := range depths { + b.Run(fmt.Sprintf("depth=%d", d), func(b *testing.B) { + b.Run("Root=Background", func(b *testing.B) { + for i := 0; i < b.N; i++ { + buildContextTree(Background(), d) + } + }) + b.Run("Root=OpenCanceler", func(b *testing.B) { + for i := 0; i < b.N; i++ { + ctx, cancel := WithCancel(Background()) + buildContextTree(ctx, d) + cancel() + } + }) + b.Run("Root=ClosedCanceler", func(b *testing.B) { + for i := 0; i < b.N; i++ { + ctx, cancel := WithCancel(Background()) + cancel() + buildContextTree(ctx, d) + } + }) + }) + } +} + +func buildContextTree(root Context, depth int) { + for d := 0; d < depth; d++ { + root, _ = WithCancel(root) + } +} + +func BenchmarkCheckCanceled(b *testing.B) { + ctx, cancel := WithCancel(Background()) + cancel() + b.Run("Err", func(b *testing.B) { + for i := 0; i < b.N; i++ { + ctx.Err() + } + }) + b.Run("Done", func(b *testing.B) { + for i := 0; i < b.N; i++ { + select { + case <-ctx.Done(): + default: + } + } + }) +} |