github.com/kdevb0x/go@v0.0.0-20180115030120-39687051e9e7/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 BenchmarkUnicodeDecoder(b *testing.B) { 137 j := []byte(`"\uD83D\uDE01"`) 138 b.SetBytes(int64(len(j))) 139 r := bytes.NewReader(j) 140 dec := NewDecoder(r) 141 var out string 142 b.ResetTimer() 143 for i := 0; i < b.N; i++ { 144 if err := dec.Decode(&out); err != nil { 145 b.Fatal("Decode:", err) 146 } 147 r.Seek(0, 0) 148 } 149 } 150 151 func BenchmarkDecoderStream(b *testing.B) { 152 b.StopTimer() 153 var buf bytes.Buffer 154 dec := NewDecoder(&buf) 155 buf.WriteString(`"` + strings.Repeat("x", 1000000) + `"` + "\n\n\n") 156 var x interface{} 157 if err := dec.Decode(&x); err != nil { 158 b.Fatal("Decode:", err) 159 } 160 ones := strings.Repeat(" 1\n", 300000) + "\n\n\n" 161 b.StartTimer() 162 for i := 0; i < b.N; i++ { 163 if i%300000 == 0 { 164 buf.WriteString(ones) 165 } 166 x = nil 167 if err := dec.Decode(&x); err != nil || x != 1.0 { 168 b.Fatalf("Decode: %v after %d", err, i) 169 } 170 } 171 } 172 173 func BenchmarkCodeUnmarshal(b *testing.B) { 174 if codeJSON == nil { 175 b.StopTimer() 176 codeInit() 177 b.StartTimer() 178 } 179 b.RunParallel(func(pb *testing.PB) { 180 for pb.Next() { 181 var r codeResponse 182 if err := Unmarshal(codeJSON, &r); err != nil { 183 b.Fatal("Unmarshal:", err) 184 } 185 } 186 }) 187 b.SetBytes(int64(len(codeJSON))) 188 } 189 190 func BenchmarkCodeUnmarshalReuse(b *testing.B) { 191 if codeJSON == nil { 192 b.StopTimer() 193 codeInit() 194 b.StartTimer() 195 } 196 b.RunParallel(func(pb *testing.PB) { 197 var r codeResponse 198 for pb.Next() { 199 if err := Unmarshal(codeJSON, &r); err != nil { 200 b.Fatal("Unmarshal:", err) 201 } 202 } 203 }) 204 // TODO(bcmills): Is there a missing b.SetBytes here? 205 } 206 207 func BenchmarkUnmarshalString(b *testing.B) { 208 data := []byte(`"hello, world"`) 209 b.RunParallel(func(pb *testing.PB) { 210 var s string 211 for pb.Next() { 212 if err := Unmarshal(data, &s); err != nil { 213 b.Fatal("Unmarshal:", err) 214 } 215 } 216 }) 217 } 218 219 func BenchmarkUnmarshalFloat64(b *testing.B) { 220 data := []byte(`3.14`) 221 b.RunParallel(func(pb *testing.PB) { 222 var f float64 223 for pb.Next() { 224 if err := Unmarshal(data, &f); err != nil { 225 b.Fatal("Unmarshal:", err) 226 } 227 } 228 }) 229 } 230 231 func BenchmarkUnmarshalInt64(b *testing.B) { 232 data := []byte(`3`) 233 b.RunParallel(func(pb *testing.PB) { 234 var x int64 235 for pb.Next() { 236 if err := Unmarshal(data, &x); err != nil { 237 b.Fatal("Unmarshal:", err) 238 } 239 } 240 }) 241 } 242 243 func BenchmarkIssue10335(b *testing.B) { 244 b.ReportAllocs() 245 j := []byte(`{"a":{ }}`) 246 b.RunParallel(func(pb *testing.PB) { 247 var s struct{} 248 for pb.Next() { 249 if err := Unmarshal(j, &s); err != nil { 250 b.Fatal(err) 251 } 252 } 253 }) 254 } 255 256 func BenchmarkUnmapped(b *testing.B) { 257 b.ReportAllocs() 258 j := []byte(`{"s": "hello", "y": 2, "o": {"x": 0}, "a": [1, 99, {"x": 1}]}`) 259 b.RunParallel(func(pb *testing.PB) { 260 var s struct{} 261 for pb.Next() { 262 if err := Unmarshal(j, &s); err != nil { 263 b.Fatal(err) 264 } 265 } 266 }) 267 }