]> Cypherpunks repositories - gostls13.git/commitdiff
context: avoid defer in the cancelCtx.Err method
authorKeegan Carruthers-Smith <keegan.csmith@gmail.com>
Sun, 15 Apr 2018 21:22:13 +0000 (22:22 +0100)
committerBrad Fitzpatrick <bradfitz@golang.org>
Sun, 15 Apr 2018 21:35:53 +0000 (21:35 +0000)
name                  old time/op  new time/op  delta
CheckCanceled/Err-4   53.5ns ± 2%  20.8ns ± 0%  -61.05%  (p=0.008 n=5+5)
CheckCanceled/Done-4  44.4ns ± 1%  44.5ns ± 0%     ~     (p=0.889 n=5+5)

Change-Id: I2c68700a2b33f8feb3d307ce7c966590a3e960af
Reviewed-on: https://go-review.googlesource.com/107137
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/context/benchmark_test.go
src/context/context.go

index 3c526dd1069570e53c19f993dc3956c4d0bee889..6dd8510ff4c437a3f3cc1eb7551024c3cf163de5 100644 (file)
@@ -96,3 +96,21 @@ func buildContextTree(root Context, depth int) {
                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:
+                       }
+               }
+       })
+}
index 06580e0465aa107886b7bc2841bf135ece44b809..1b4fa41b8cc32476134a95840692f967b03c6446 100644 (file)
@@ -334,8 +334,9 @@ func (c *cancelCtx) Done() <-chan struct{} {
 
 func (c *cancelCtx) Err() error {
        c.mu.Lock()
-       defer c.mu.Unlock()
-       return c.err
+       err := c.err
+       c.mu.Unlock()
+       return err
 }
 
 func (c *cancelCtx) String() string {