Home | History | Annotate | Download | only in json
      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 	enc := NewEncoder(ioutil.Discard)
     86 	for i := 0; i < b.N; i++ {
     87 		if err := enc.Encode(&codeStruct); err != nil {
     88 			b.Fatal("Encode:", err)
     89 		}
     90 	}
     91 	b.SetBytes(int64(len(codeJSON)))
     92 }
     93 
     94 func BenchmarkCodeMarshal(b *testing.B) {
     95 	if codeJSON == nil {
     96 		b.StopTimer()
     97 		codeInit()
     98 		b.StartTimer()
     99 	}
    100 	for i := 0; i < b.N; i++ {
    101 		if _, err := Marshal(&codeStruct); err != nil {
    102 			b.Fatal("Marshal:", err)
    103 		}
    104 	}
    105 	b.SetBytes(int64(len(codeJSON)))
    106 }
    107 
    108 func BenchmarkCodeDecoder(b *testing.B) {
    109 	if codeJSON == nil {
    110 		b.StopTimer()
    111 		codeInit()
    112 		b.StartTimer()
    113 	}
    114 	var buf bytes.Buffer
    115 	dec := NewDecoder(&buf)
    116 	var r codeResponse
    117 	for i := 0; i < b.N; i++ {
    118 		buf.Write(codeJSON)
    119 		// hide EOF
    120 		buf.WriteByte('\n')
    121 		buf.WriteByte('\n')
    122 		buf.WriteByte('\n')
    123 		if err := dec.Decode(&r); err != nil {
    124 			b.Fatal("Decode:", err)
    125 		}
    126 	}
    127 	b.SetBytes(int64(len(codeJSON)))
    128 }
    129 
    130 func BenchmarkDecoderStream(b *testing.B) {
    131 	b.StopTimer()
    132 	var buf bytes.Buffer
    133 	dec := NewDecoder(&buf)
    134 	buf.WriteString(`"` + strings.Repeat("x", 1000000) + `"` + "\n\n\n")
    135 	var x interface{}
    136 	if err := dec.Decode(&x); err != nil {
    137 		b.Fatal("Decode:", err)
    138 	}
    139 	ones := strings.Repeat(" 1\n", 300000) + "\n\n\n"
    140 	b.StartTimer()
    141 	for i := 0; i < b.N; i++ {
    142 		if i%300000 == 0 {
    143 			buf.WriteString(ones)
    144 		}
    145 		x = nil
    146 		if err := dec.Decode(&x); err != nil || x != 1.0 {
    147 			b.Fatalf("Decode: %v after %d", err, i)
    148 		}
    149 	}
    150 }
    151 
    152 func BenchmarkCodeUnmarshal(b *testing.B) {
    153 	if codeJSON == nil {
    154 		b.StopTimer()
    155 		codeInit()
    156 		b.StartTimer()
    157 	}
    158 	for i := 0; i < b.N; i++ {
    159 		var r codeResponse
    160 		if err := Unmarshal(codeJSON, &r); err != nil {
    161 			b.Fatal("Unmarshal:", err)
    162 		}
    163 	}
    164 	b.SetBytes(int64(len(codeJSON)))
    165 }
    166 
    167 func BenchmarkCodeUnmarshalReuse(b *testing.B) {
    168 	if codeJSON == nil {
    169 		b.StopTimer()
    170 		codeInit()
    171 		b.StartTimer()
    172 	}
    173 	var r codeResponse
    174 	for i := 0; i < b.N; i++ {
    175 		if err := Unmarshal(codeJSON, &r); err != nil {
    176 			b.Fatal("Unmarshal:", err)
    177 		}
    178 	}
    179 }
    180 
    181 func BenchmarkUnmarshalString(b *testing.B) {
    182 	data := []byte(`"hello, world"`)
    183 	var s string
    184 
    185 	for i := 0; i < b.N; i++ {
    186 		if err := Unmarshal(data, &s); err != nil {
    187 			b.Fatal("Unmarshal:", err)
    188 		}
    189 	}
    190 }
    191 
    192 func BenchmarkUnmarshalFloat64(b *testing.B) {
    193 	var f float64
    194 	data := []byte(`3.14`)
    195 
    196 	for i := 0; i < b.N; i++ {
    197 		if err := Unmarshal(data, &f); err != nil {
    198 			b.Fatal("Unmarshal:", err)
    199 		}
    200 	}
    201 }
    202 
    203 func BenchmarkUnmarshalInt64(b *testing.B) {
    204 	var x int64
    205 	data := []byte(`3`)
    206 
    207 	for i := 0; i < b.N; i++ {
    208 		if err := Unmarshal(data, &x); err != nil {
    209 			b.Fatal("Unmarshal:", err)
    210 		}
    211 	}
    212 }
    213 
    214 func BenchmarkIssue10335(b *testing.B) {
    215 	b.ReportAllocs()
    216 	var s struct{}
    217 	j := []byte(`{"a":{ }}`)
    218 	for n := 0; n < b.N; n++ {
    219 		if err := Unmarshal(j, &s); err != nil {
    220 			b.Fatal(err)
    221 		}
    222 	}
    223 }
    224