github.com/mattn/go@v0.0.0-20171011075504-07f7db3ea99f/src/encoding/json/bench_test.go (about) 1 // Copyright 2011 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 5 // Large data benchmark. 6 // The JSON data is a summary of agl's changes in the 7 // go, webkit, and chromium open source projects. 8 // We benchmark converting between the JSON form 9 // and in-memory data structures. 10 11 package json 12 13 import ( 14 "bytes" 15 "compress/gzip" 16 "io/ioutil" 17 "os" 18 "strings" 19 "testing" 20 ) 21 22 type codeResponse struct { 23 Tree *codeNode `json:"tree"` 24 Username string `json:"username"` 25 } 26 27 type codeNode struct { 28 Name string `json:"name"` 29 Kids []*codeNode `json:"kids"` 30 CLWeight float64 `json:"cl_weight"` 31 Touches int `json:"touches"` 32 MinT int64 `json:"min_t"` 33 MaxT int64 `json:"max_t"` 34 MeanT int64 `json:"mean_t"` 35 } 36 37 var codeJSON []byte 38 var codeStruct codeResponse 39 40 func codeInit() { 41 f, err := os.Open("testdata/code.json.gz") 42 if err != nil { 43 panic(err) 44 } 45 defer f.Close() 46 gz, err := gzip.NewReader(f) 47 if err != nil { 48 panic(err) 49 } 50 data, err := ioutil.ReadAll(gz) 51 if err != nil { 52 panic(err) 53 } 54 55 codeJSON = data 56 57 if err := Unmarshal(codeJSON, &codeStruct); err != nil { 58 panic("unmarshal code.json: " + err.Error()) 59 } 60 61 if data, err = Marshal(&codeStruct); err != nil { 62 panic("marshal code.json: " + err.Error()) 63 } 64 65 if !bytes.Equal(data, codeJSON) { 66 println("different lengths", len(data), len(codeJSON)) 67 for i := 0; i < len(data) && i < len(codeJSON); i++ { 68 if data[i] != codeJSON[i] { 69 println("re-marshal: changed at byte", i) 70 println("orig: ", string(codeJSON[i-10:i+10])) 71 println("new: ", string(data[i-10:i+10])) 72 break 73 } 74 } 75 panic("re-marshal code.json: different result") 76 } 77 } 78 79 func BenchmarkCodeEncoder(b *testing.B) { 80 if codeJSON == nil { 81 b.StopTimer() 82 codeInit() 83 b.StartTimer() 84 } 85 b.RunParallel(func(pb *testing.PB) { 86 enc := NewEncoder(ioutil.Discard) 87 for pb.Next() { 88 if err := enc.Encode(&codeStruct); err != nil { 89 b.Fatal("Encode:", err) 90 } 91 } 92 }) 93 b.SetBytes(int64(len(codeJSON))) 94 } 95 96 func BenchmarkCodeMarshal(b *testing.B) { 97 if codeJSON == nil { 98 b.StopTimer() 99 codeInit() 100 b.StartTimer() 101 } 102 b.RunParallel(func(pb *testing.PB) { 103 for pb.Next() { 104 if _, err := Marshal(&codeStruct); err != nil { 105 b.Fatal("Marshal:", err) 106 } 107 } 108 }) 109 b.SetBytes(int64(len(codeJSON))) 110 } 111 112 func BenchmarkCodeDecoder(b *testing.B) { 113 if codeJSON == nil { 114 b.StopTimer() 115 codeInit() 116 b.StartTimer() 117 } 118 b.RunParallel(func(pb *testing.PB) { 119 var buf bytes.Buffer 120 dec := NewDecoder(&buf) 121 var r codeResponse 122 for pb.Next() { 123 buf.Write(codeJSON) 124 // hide EOF 125 buf.WriteByte('\n') 126 buf.WriteByte('\n') 127 buf.WriteByte('\n') 128 if err := dec.Decode(&r); err != nil { 129 b.Fatal("Decode:", err) 130 } 131 } 132 }) 133 b.SetBytes(int64(len(codeJSON))) 134 } 135 136 func BenchmarkDecoderStream(b *testing.B) { 137 b.StopTimer() 138 var buf bytes.Buffer 139 dec := NewDecoder(&buf) 140 buf.WriteString(`"` + strings.Repeat("x", 1000000) + `"` + "\n\n\n") 141 var x interface{} 142 if err := dec.Decode(&x); err != nil { 143 b.Fatal("Decode:", err) 144 } 145 ones := strings.Repeat(" 1\n", 300000) + "\n\n\n" 146 b.StartTimer() 147 for i := 0; i < b.N; i++ { 148 if i%300000 == 0 { 149 buf.WriteString(ones) 150 } 151 x = nil 152 if err := dec.Decode(&x); err != nil || x != 1.0 { 153 b.Fatalf("Decode: %v after %d", err, i) 154 } 155 } 156 } 157 158 func BenchmarkCodeUnmarshal(b *testing.B) { 159 if codeJSON == nil { 160 b.StopTimer() 161 codeInit() 162 b.StartTimer() 163 } 164 b.RunParallel(func(pb *testing.PB) { 165 for pb.Next() { 166 var r codeResponse 167 if err := Unmarshal(codeJSON, &r); err != nil { 168 b.Fatal("Unmarshal:", err) 169 } 170 } 171 }) 172 b.SetBytes(int64(len(codeJSON))) 173 } 174 175 func BenchmarkCodeUnmarshalReuse(b *testing.B) { 176 if codeJSON == nil { 177 b.StopTimer() 178 codeInit() 179 b.StartTimer() 180 } 181 b.RunParallel(func(pb *testing.PB) { 182 var r codeResponse 183 for pb.Next() { 184 if err := Unmarshal(codeJSON, &r); err != nil { 185 b.Fatal("Unmarshal:", err) 186 } 187 } 188 }) 189 // TODO(bcmills): Is there a missing b.SetBytes here? 190 } 191 192 func BenchmarkUnmarshalString(b *testing.B) { 193 data := []byte(`"hello, world"`) 194 b.RunParallel(func(pb *testing.PB) { 195 var s string 196 for pb.Next() { 197 if err := Unmarshal(data, &s); err != nil { 198 b.Fatal("Unmarshal:", err) 199 } 200 } 201 }) 202 } 203 204 func BenchmarkUnmarshalFloat64(b *testing.B) { 205 data := []byte(`3.14`) 206 b.RunParallel(func(pb *testing.PB) { 207 var f float64 208 for pb.Next() { 209 if err := Unmarshal(data, &f); err != nil { 210 b.Fatal("Unmarshal:", err) 211 } 212 } 213 }) 214 } 215 216 func BenchmarkUnmarshalInt64(b *testing.B) { 217 data := []byte(`3`) 218 b.RunParallel(func(pb *testing.PB) { 219 var x int64 220 for pb.Next() { 221 if err := Unmarshal(data, &x); err != nil { 222 b.Fatal("Unmarshal:", err) 223 } 224 } 225 }) 226 } 227 228 func BenchmarkIssue10335(b *testing.B) { 229 b.ReportAllocs() 230 j := []byte(`{"a":{ }}`) 231 b.RunParallel(func(pb *testing.PB) { 232 var s struct{} 233 for pb.Next() { 234 if err := Unmarshal(j, &s); err != nil { 235 b.Fatal(err) 236 } 237 } 238 }) 239 } 240 241 func BenchmarkUnmapped(b *testing.B) { 242 b.ReportAllocs() 243 j := []byte(`{"s": "hello", "y": 2, "o": {"x": 0}, "a": [1, 99, {"x": 1}]}`) 244 b.RunParallel(func(pb *testing.PB) { 245 var s struct{} 246 for pb.Next() { 247 if err := Unmarshal(j, &s); err != nil { 248 b.Fatal(err) 249 } 250 } 251 }) 252 }