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  }