]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/json: parallelize most benchmarks
authorBryan C. Mills <bcmills@google.com>
Fri, 10 Feb 2017 20:48:30 +0000 (15:48 -0500)
committerBryan Mills <bcmills@google.com>
Wed, 26 Apr 2017 19:23:06 +0000 (19:23 +0000)
Don't bother with BenchmarkDecoderStream — it's doing something subtle
with the input buffer that isn't easy to replicate in a parallel test.

Results remain comparable with the non-parallel version with -cpu=1:

benchmark                          old ns/op     new ns/op     delta
BenchmarkCodeEncoder               22815832      21058729      -7.70%
BenchmarkCodeEncoder-6             22190561      3579757       -83.87%
BenchmarkCodeMarshal               25356621      25396429      +0.16%
BenchmarkCodeMarshal-6             25359813      4944908       -80.50%
BenchmarkCodeDecoder               94794556      88016360      -7.15%
BenchmarkCodeDecoder-6             93795028      16726283      -82.17%
BenchmarkDecoderStream             532           583           +9.59%
BenchmarkDecoderStream-6           598           550           -8.03%
BenchmarkCodeUnmarshal             97644168      89162504      -8.69%
BenchmarkCodeUnmarshal-6           96615302      17036419      -82.37%
BenchmarkCodeUnmarshalReuse        91747073      90298479      -1.58%
BenchmarkCodeUnmarshalReuse-6      89397165      15518005      -82.64%
BenchmarkUnmarshalString           808           843           +4.33%
BenchmarkUnmarshalString-6         912           220           -75.88%
BenchmarkUnmarshalFloat64          695           732           +5.32%
BenchmarkUnmarshalFloat64-6        710           191           -73.10%
BenchmarkUnmarshalInt64            635           640           +0.79%
BenchmarkUnmarshalInt64-6          618           185           -70.06%
BenchmarkIssue10335                916           947           +3.38%
BenchmarkIssue10335-6              879           216           -75.43%
BenchmarkNumberIsValid             34.7          34.3          -1.15%
BenchmarkNumberIsValid-6           34.9          36.7          +5.16%
BenchmarkNumberIsValidRegexp       1174          1121          -4.51%
BenchmarkNumberIsValidRegexp-6     1134          1119          -1.32%
BenchmarkSkipValue                 20506938      20708060      +0.98%
BenchmarkSkipValue-6               21627665      22375630      +3.46%
BenchmarkEncoderEncode             690           726           +5.22%
BenchmarkEncoderEncode-6           649           157           -75.81%

benchmark                    old MB/s     new MB/s     speedup
BenchmarkCodeEncoder         85.05        92.15        1.08x
BenchmarkCodeEncoder-6       87.45        542.07       6.20x
BenchmarkCodeMarshal         76.53        76.41        1.00x
BenchmarkCodeMarshal-6       76.52        392.42       5.13x
BenchmarkCodeDecoder         20.47        22.05        1.08x
BenchmarkCodeDecoder-6       20.69        116.01       5.61x
BenchmarkCodeUnmarshal       19.87        21.76        1.10x
BenchmarkCodeUnmarshal-6     20.08        113.90       5.67x
BenchmarkSkipValue           90.55        89.67        0.99x
BenchmarkSkipValue-6         90.83        87.80        0.97x

benchmark                    old allocs     new allocs     delta
BenchmarkIssue10335          4              4              +0.00%
BenchmarkIssue10335-6        4              4              +0.00%
BenchmarkEncoderEncode       1              1              +0.00%
BenchmarkEncoderEncode-6     1              1              +0.00%

benchmark                    old bytes     new bytes     delta
BenchmarkIssue10335          320           320           +0.00%
BenchmarkIssue10335-6        320           320           +0.00%
BenchmarkEncoderEncode       8             8             +0.00%
BenchmarkEncoderEncode-6     8             8             +0.00%

updates #18177

Change-Id: Ia4f5bf5ac0afbadb1705ed9f9e1b39dabba67b40
Reviewed-on: https://go-review.googlesource.com/36724
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/encoding/json/bench_test.go
src/encoding/json/stream_test.go

index ec5a88a4e25bdbd77b9bbd3567fe7a1562085cd7..85d7ae043b8caa77ca263e37ac11bd91c6b7fff2 100644 (file)
@@ -82,12 +82,14 @@ func BenchmarkCodeEncoder(b *testing.B) {
                codeInit()
                b.StartTimer()
        }
-       enc := NewEncoder(ioutil.Discard)
-       for i := 0; i < b.N; i++ {
-               if err := enc.Encode(&codeStruct); err != nil {
-                       b.Fatal("Encode:", err)
+       b.RunParallel(func(pb *testing.PB) {
+               enc := NewEncoder(ioutil.Discard)
+               for pb.Next() {
+                       if err := enc.Encode(&codeStruct); err != nil {
+                               b.Fatal("Encode:", err)
+                       }
                }
-       }
+       })
        b.SetBytes(int64(len(codeJSON)))
 }
 
@@ -97,11 +99,13 @@ func BenchmarkCodeMarshal(b *testing.B) {
                codeInit()
                b.StartTimer()
        }
-       for i := 0; i < b.N; i++ {
-               if _, err := Marshal(&codeStruct); err != nil {
-                       b.Fatal("Marshal:", err)
+       b.RunParallel(func(pb *testing.PB) {
+               for pb.Next() {
+                       if _, err := Marshal(&codeStruct); err != nil {
+                               b.Fatal("Marshal:", err)
+                       }
                }
-       }
+       })
        b.SetBytes(int64(len(codeJSON)))
 }
 
@@ -111,19 +115,21 @@ func BenchmarkCodeDecoder(b *testing.B) {
                codeInit()
                b.StartTimer()
        }
-       var buf bytes.Buffer
-       dec := NewDecoder(&buf)
-       var r codeResponse
-       for i := 0; i < b.N; i++ {
-               buf.Write(codeJSON)
-               // hide EOF
-               buf.WriteByte('\n')
-               buf.WriteByte('\n')
-               buf.WriteByte('\n')
-               if err := dec.Decode(&r); err != nil {
-                       b.Fatal("Decode:", err)
+       b.RunParallel(func(pb *testing.PB) {
+               var buf bytes.Buffer
+               dec := NewDecoder(&buf)
+               var r codeResponse
+               for pb.Next() {
+                       buf.Write(codeJSON)
+                       // hide EOF
+                       buf.WriteByte('\n')
+                       buf.WriteByte('\n')
+                       buf.WriteByte('\n')
+                       if err := dec.Decode(&r); err != nil {
+                               b.Fatal("Decode:", err)
+                       }
                }
-       }
+       })
        b.SetBytes(int64(len(codeJSON)))
 }
 
@@ -155,12 +161,14 @@ func BenchmarkCodeUnmarshal(b *testing.B) {
                codeInit()
                b.StartTimer()
        }
-       for i := 0; i < b.N; i++ {
-               var r codeResponse
-               if err := Unmarshal(codeJSON, &r); err != nil {
-                       b.Fatal("Unmarshal:", err)
+       b.RunParallel(func(pb *testing.PB) {
+               for pb.Next() {
+                       var r codeResponse
+                       if err := Unmarshal(codeJSON, &r); err != nil {
+                               b.Fatal("Unmarshal:", err)
+                       }
                }
-       }
+       })
        b.SetBytes(int64(len(codeJSON)))
 }
 
@@ -170,65 +178,75 @@ func BenchmarkCodeUnmarshalReuse(b *testing.B) {
                codeInit()
                b.StartTimer()
        }
-       var r codeResponse
-       for i := 0; i < b.N; i++ {
-               if err := Unmarshal(codeJSON, &r); err != nil {
-                       b.Fatal("Unmarshal:", err)
+       b.RunParallel(func(pb *testing.PB) {
+               var r codeResponse
+               for pb.Next() {
+                       if err := Unmarshal(codeJSON, &r); err != nil {
+                               b.Fatal("Unmarshal:", err)
+                       }
                }
-       }
+       })
+       // TODO(bcmills): Is there a missing b.SetBytes here?
 }
 
 func BenchmarkUnmarshalString(b *testing.B) {
        data := []byte(`"hello, world"`)
-       var s string
-
-       for i := 0; i < b.N; i++ {
-               if err := Unmarshal(data, &s); err != nil {
-                       b.Fatal("Unmarshal:", err)
+       b.RunParallel(func(pb *testing.PB) {
+               var s string
+               for pb.Next() {
+                       if err := Unmarshal(data, &s); err != nil {
+                               b.Fatal("Unmarshal:", err)
+                       }
                }
-       }
+       })
 }
 
 func BenchmarkUnmarshalFloat64(b *testing.B) {
-       var f float64
        data := []byte(`3.14`)
-
-       for i := 0; i < b.N; i++ {
-               if err := Unmarshal(data, &f); err != nil {
-                       b.Fatal("Unmarshal:", err)
+       b.RunParallel(func(pb *testing.PB) {
+               var f float64
+               for pb.Next() {
+                       if err := Unmarshal(data, &f); err != nil {
+                               b.Fatal("Unmarshal:", err)
+                       }
                }
-       }
+       })
 }
 
 func BenchmarkUnmarshalInt64(b *testing.B) {
-       var x int64
        data := []byte(`3`)
-
-       for i := 0; i < b.N; i++ {
-               if err := Unmarshal(data, &x); err != nil {
-                       b.Fatal("Unmarshal:", err)
+       b.RunParallel(func(pb *testing.PB) {
+               var x int64
+               for pb.Next() {
+                       if err := Unmarshal(data, &x); err != nil {
+                               b.Fatal("Unmarshal:", err)
+                       }
                }
-       }
+       })
 }
 
 func BenchmarkIssue10335(b *testing.B) {
        b.ReportAllocs()
-       var s struct{}
        j := []byte(`{"a":{ }}`)
-       for n := 0; n < b.N; n++ {
-               if err := Unmarshal(j, &s); err != nil {
-                       b.Fatal(err)
+       b.RunParallel(func(pb *testing.PB) {
+               var s struct{}
+               for pb.Next() {
+                       if err := Unmarshal(j, &s); err != nil {
+                               b.Fatal(err)
+                       }
                }
-       }
+       })
 }
 
 func BenchmarkUnmapped(b *testing.B) {
        b.ReportAllocs()
-       var s struct{}
        j := []byte(`{"s": "hello", "y": 2, "o": {"x": 0}, "a": [1, 99, {"x": 1}]}`)
-       for n := 0; n < b.N; n++ {
-               if err := Unmarshal(j, &s); err != nil {
-                       b.Fatal(err)
+       b.RunParallel(func(pb *testing.PB) {
+               var s struct{}
+               for pb.Next() {
+                       if err := Unmarshal(j, &s); err != nil {
+                               b.Fatal(err)
+                       }
                }
-       }
+       })
 }
index 84edeb187c259240facd75ae2e62fffc75e29539..d0b3ffbce93a921c01897cceccdb3e0c33a49299 100644 (file)
@@ -268,11 +268,13 @@ func BenchmarkEncoderEncode(b *testing.B) {
                X, Y string
        }
        v := &T{"foo", "bar"}
-       for i := 0; i < b.N; i++ {
-               if err := NewEncoder(ioutil.Discard).Encode(v); err != nil {
-                       b.Fatal(err)
+       b.RunParallel(func(pb *testing.PB) {
+               for pb.Next() {
+                       if err := NewEncoder(ioutil.Discard).Encode(v); err != nil {
+                               b.Fatal(err)
+                       }
                }
-       }
+       })
 }
 
 type tokenStreamCase struct {