github.com/urso/go-structform@v0.0.2/bench/bench_json_decode_test.go (about) 1 package bench 2 3 import ( 4 "bytes" 5 "io" 6 "io/ioutil" 7 "testing" 8 9 stdjson "encoding/json" 10 ) 11 12 func BenchmarkDecodeBeatsEvents(b *testing.B) { 13 runPaths := func(paths ...string) func(*testing.B) { 14 return func(b *testing.B) { 15 jsonContent := readFile(paths...) 16 17 b.Run("std-json", 18 makeBenchmarkDecodeBeatsEvents(stdJSONBufDecoder, jsonContent)) 19 20 // panic: fails to parse events 21 //b.Run("jsoniter", 22 // makeBenchmarkDecodeBeatsEvents(jsoniterBufDecoder, jsonContent)) 23 24 b.Run("structform-json", 25 makeBenchmarkDecodeBeatsEvents(structformJSONBufDecoder(0), jsonContent)) 26 b.Run("structform-json-keycache", 27 makeBenchmarkDecodeBeatsEvents(structformJSONBufDecoder(1000), jsonContent)) 28 29 ubjsonContent := readFileEncoded(structformUBJSONEncoder, paths...) 30 b.Run("structform-ubjson", 31 makeBenchmarkDecodeBeatsEvents(structformUBJSONBufDecoder(0), ubjsonContent)) 32 b.Run("structform-ubjson-keycache", 33 makeBenchmarkDecodeBeatsEvents(structformUBJSONBufDecoder(1000), ubjsonContent)) 34 35 cborContent := readFileEncoded(structformCBORLEncoder, paths...) 36 b.Run("structform-cborl", 37 makeBenchmarkDecodeBeatsEvents(structformCBORLBufDecoder(0), cborContent)) 38 b.Run("structform-cborl-keycache", 39 makeBenchmarkDecodeBeatsEvents(structformCBORLBufDecoder(1000), cborContent)) 40 41 } 42 } 43 44 b.Run("packetbeat", runPaths("files/packetbeat_events.json")) 45 b.Run("metricbeat", runPaths("files/metricbeat_events.json")) 46 b.Run("filebeat", runPaths("files/filebeat_events.json")) 47 } 48 49 func BenchmarkEncodeBeatsEvents(b *testing.B) { 50 runPaths := func(paths ...string) func(*testing.B) { 51 events := loadEvents(paths...) 52 return func(b *testing.B) { 53 b.Run("std-json", makeBenchmarkEncodeEvents(stdJSONEncoder, events)) 54 b.Run("structform-json", makeBenchmarkEncodeEvents(structformJSONEncoder, events)) 55 b.Run("structform-ubjson", makeBenchmarkEncodeEvents(structformUBJSONEncoder, events)) 56 b.Run("structform-cborl", makeBenchmarkEncodeEvents(structformCBORLEncoder, events)) 57 } 58 } 59 60 b.Run("packetbeat", runPaths("files/packetbeat_events.json")) 61 b.Run("metricbeat", runPaths("files/metricbeat_events.json")) 62 b.Run("filebeat", runPaths("files/filebeat_events.json")) 63 } 64 65 func BenchmarkTranscodeBeatsEvents(b *testing.B) { 66 runPaths := func(paths ...string) func(*testing.B) { 67 return func(b *testing.B) { 68 b.Run("structform-cborl->json", makeBenchmarkTranscodeEvents( 69 structformCBORLEncoder, 70 makeCBORL2JSONTranscoder, 71 paths..., 72 )) 73 b.Run("structform-ubjson->json", makeBenchmarkTranscodeEvents( 74 structformUBJSONEncoder, 75 makeUBJSON2JSONTranscoder, 76 paths..., 77 )) 78 } 79 } 80 81 b.Run("packetbeat", runPaths("files/packetbeat_events.json")) 82 b.Run("metricbeat", runPaths("files/metricbeat_events.json")) 83 b.Run("filebeat", runPaths("files/filebeat_events.json")) 84 } 85 86 func makeBenchmarkDecodeBeatsEvents( 87 factory decoderFactory, 88 content []byte, 89 ) func(*testing.B) { 90 91 return func(b *testing.B) { 92 b.SetBytes(int64(len(content))) 93 for i := 0; i < b.N; i++ { 94 decode := factory(content) 95 96 for { 97 var to map[string]interface{} 98 99 if err := decode(&to); err != nil { 100 if err != io.EOF { 101 b.Error(err) 102 } 103 break 104 } 105 } 106 } 107 } 108 } 109 110 func makeBenchmarkEncodeEvents(factory encoderFactory, events []map[string]interface{}) func(*testing.B) { 111 var buf bytes.Buffer 112 buf.Grow(16 * 1024) 113 encode := factory(&buf) 114 115 return func(b *testing.B) { 116 for i := 0; i < b.N; i++ { 117 var written int64 118 119 for _, event := range events { 120 buf.Reset() 121 if err := encode(event); err != nil { 122 b.Error(err) 123 return 124 } 125 written += int64(buf.Len()) 126 } 127 b.SetBytes(written) 128 } 129 } 130 } 131 132 func makeBenchmarkTranscodeEvents( 133 fEnc encoderFactory, 134 fTransc transcodeFactory, 135 paths ...string, 136 ) func(b *testing.B) { 137 content := readFileEncoded(fEnc, paths...) 138 139 var buf bytes.Buffer 140 transcode := fTransc(&buf) 141 return func(b *testing.B) { 142 for i := 0; i < b.N; i++ { 143 buf.Reset() 144 err := transcode(content) 145 if err != nil { 146 b.Error(err) 147 return 148 } 149 150 content := buf.Bytes() 151 n := len(content) 152 b.SetBytes(int64(n)) 153 } 154 } 155 } 156 157 func loadEvents(paths ...string) []map[string]interface{} { 158 content := readFile(paths...) 159 160 var events []map[string]interface{} 161 dec := stdjson.NewDecoder(bytes.NewReader(content)) 162 for { 163 var e map[string]interface{} 164 if err := dec.Decode(&e); err != nil { 165 if err == io.EOF { 166 break 167 } 168 169 panic(err) 170 } 171 172 events = append(events, e) 173 } 174 175 return events 176 } 177 178 func readFileEncoded(encFactory encoderFactory, paths ...string) []byte { 179 var buf bytes.Buffer 180 enc := encFactory(&buf) 181 182 events := loadEvents(paths...) 183 for _, event := range events { 184 err := enc(event) 185 if err != nil { 186 panic(err) 187 } 188 } 189 190 return buf.Bytes() 191 } 192 193 func readFile(paths ...string) []byte { 194 var buf bytes.Buffer 195 196 for _, p := range paths { 197 content, err := ioutil.ReadFile(p) 198 if err != nil { 199 if err != nil { 200 panic(err) 201 } 202 } 203 204 buf.Write(content) 205 } 206 207 return buf.Bytes() 208 }