From b8e39c37e10fb18e32e3a5fe9d7b03b8da12492c Mon Sep 17 00:00:00 2001 From: Neil O'Toole Date: Sun, 3 Oct 2021 16:40:13 -0600 Subject: [PATCH] wip: refactoring benchmarks --- benchmark_test.go | 265 +++++++--------------------------------------- 1 file changed, 41 insertions(+), 224 deletions(-) diff --git a/benchmark_test.go b/benchmark_test.go index 76a1a3c..69d938b 100644 --- a/benchmark_test.go +++ b/benchmark_test.go @@ -4,257 +4,74 @@ import ( "bytes" stdj "encoding/json" "io" - "io/ioutil" "testing" "time" - segmentj "github.com/segmentio/encoding/json" - "github.com/neilotoole/jsoncolor" nwidgerj "github.com/nwidger/jsoncolor" ) -func BenchmarkEncoder_Encode(b *testing.B) { +func BenchmarkEncode(b *testing.B) { benchmarks := []struct { name string indent bool color bool fn newEncoderFunc }{ - {name: "stdlib_no_indent", fn: newEncStdlib}, + {name: "stdlib_indent_no", fn: newEncStdlib}, + {name: "stdlib_indent_yes", fn: newEncStdlib, indent: true}, + {name: "segmentj_indent_no", fn: newEncSegmentj}, + {name: "segmentj_indent_yes", fn: newEncSegmentj, indent: true}, + {name: "neilotoole_indent_no_color_no", fn: newEncNeilotoole}, + {name: "neilotoole_indent_yes_color_no", fn: newEncNeilotoole, indent: true}, + {name: "neilotoole_indent_no_color_yes", fn: newEncNeilotoole, color: true}, + {name: "neilotoole_indent_yes_color_yes", fn: newEncNeilotoole, indent: true, color: true}, + {name: "nwidger_indent_no_color_no", fn: newEncNwidger}, + {name: "nwidger_indent_yes_color_no", fn: newEncNwidger, indent: true}, + {name: "nwidger_indent_no_color_yes", fn: newEncNwidger, color: true}, + {name: "nwidger_indent_yes_color_yes", fn: newEncNwidger, indent: true, color: true}, } for _, bm := range benchmarks { bm := bm b.Run(bm.name, func(b *testing.B) { - - }) - } - -} - -// The following benchmarks compare the encoding performance -// of JSON encoders. These are: -// -// - stdj: the std lib json encoder -// - segmentj: the encoder by segment.io -// - jsoncolor: this fork of segmentj that supports color -func Benchmark_stdlib_NoIndent(b *testing.B) { - b.ReportAllocs() - recs := makeBenchRecs() - b.ResetTimer() - - for n := 0; n < b.N; n++ { - enc := stdj.NewEncoder(ioutil.Discard) - enc.SetEscapeHTML(false) - - for i := range recs { - err := enc.Encode(recs[i]) - if err != nil { - b.Error(err) - } - } - } -} - -func Benchmark_stdlib_Indent(b *testing.B) { - b.ReportAllocs() - recs := makeBenchRecs() - b.ResetTimer() - - for n := 0; n < b.N; n++ { - enc := stdj.NewEncoder(ioutil.Discard) - enc.SetEscapeHTML(false) - enc.SetIndent("", " ") - - for i := range recs { - err := enc.Encode(recs[i]) - if err != nil { - b.Error(err) - } - } - } -} - -func Benchmark_segmentj_NoIndent(b *testing.B) { - b.ReportAllocs() - recs := makeBenchRecs() - b.ResetTimer() - - for n := 0; n < b.N; n++ { - enc := segmentj.NewEncoder(ioutil.Discard) - enc.SetEscapeHTML(false) - - for i := range recs { - err := enc.Encode(recs[i]) - if err != nil { - b.Error(err) + b.ReportAllocs() + recs := makeBenchRecs() + b.ResetTimer() + + for n := 0; n < b.N; n++ { + w := &bytes.Buffer{} + enc := bm.fn(w, bm.indent, bm.color) + + for i := range recs { + err := enc.Encode(recs[i]) + if err != nil { + b.Error(err) + } + } } - } - } -} - -func Benchmark_segmentj_Indent(b *testing.B) { - b.ReportAllocs() - recs := makeBenchRecs() - b.ResetTimer() - - for n := 0; n < b.N; n++ { - enc := segmentj.NewEncoder(ioutil.Discard) - enc.SetEscapeHTML(false) - enc.SetIndent("", " ") - - for i := range recs { - err := enc.Encode(recs[i]) - if err != nil { - b.Error(err) - } - } - } -} - -func Benchmark_neilotoolejsoncolor_NoIndent(b *testing.B) { - b.ReportAllocs() - recs := makeBenchRecs() - b.ResetTimer() - - for n := 0; n < b.N; n++ { - enc := jsoncolor.NewEncoder(ioutil.Discard) - enc.SetEscapeHTML(false) - - for i := range recs { - err := enc.Encode(recs[i]) - if err != nil { - b.Error(err) - } - } - } -} - -func Benchmark_neilotoolejsoncolor_Indent(b *testing.B) { - b.ReportAllocs() - recs := makeBenchRecs() - b.ResetTimer() - - for n := 0; n < b.N; n++ { - enc := jsoncolor.NewEncoder(ioutil.Discard) - enc.SetEscapeHTML(false) - enc.SetIndent("", " ") - - for i := range recs { - err := enc.Encode(recs[i]) - if err != nil { - b.Error(err) - } - } - } -} - -func Benchmark_neilotoolejsoncolor_NoIndent_Color(b *testing.B) { - b.ReportAllocs() - recs := makeBenchRecs() - b.ResetTimer() - - for n := 0; n < b.N; n++ { - enc := jsoncolor.NewEncoder(ioutil.Discard) - enc.SetEscapeHTML(false) - enc.SetColors(jsoncolor.DefaultColors()) - - for i := range recs { - err := enc.Encode(recs[i]) - if err != nil { - b.Error(err) - } - } - } -} - -func Benchmark_neilotoolejsoncolor_Indent_Color(b *testing.B) { - b.ReportAllocs() - recs := makeBenchRecs() - b.ResetTimer() - - for n := 0; n < b.N; n++ { - enc := jsoncolor.NewEncoder(ioutil.Discard) - enc.SetEscapeHTML(false) - enc.SetIndent("", " ") - enc.SetColors(jsoncolor.DefaultColors()) - - for i := range recs { - err := enc.Encode(recs[i]) - if err != nil { - b.Error(err) - } - } - } -} - -func Benchmark_nwidgerjsoncolor_Indent_Color(b *testing.B) { - b.ReportAllocs() - recs := makeBenchRecs() - buf := &bytes.Buffer{} - b.ResetTimer() - - for n := 0; n < b.N; n++ { - f := newNwidgerColorFormatter() - enc := nwidgerj.NewEncoderWithFormatter(buf, f) - enc.SetEscapeHTML(false) - enc.SetIndent("", " ") - - for i := range recs { - err := enc.Encode(recs[i]) - if err != nil { - b.Error(err) - } - } - } -} - -func Benchmark_nwidgerjsoncolor_NoIndent_Color(b *testing.B) { - b.ReportAllocs() - recs := makeBenchRecs() - buf := &bytes.Buffer{} - b.ResetTimer() - - for n := 0; n < b.N; n++ { - f := newNwidgerColorFormatter() - enc := nwidgerj.NewEncoderWithFormatter(buf, f) - enc.SetEscapeHTML(false) - for i := range recs { - err := enc.Encode(recs[i]) - if err != nil { - b.Error(err) - } - } + }) } } -func newNwidgerColorFormatter() *nwidgerj.Formatter { - f := nwidgerj.NewFormatter() - f.SpaceColor = nwidgerj.DefaultSpaceColor - f.CommaColor = nwidgerj.DefaultCommaColor - f.ColonColor = nwidgerj.DefaultColonColor - f.ObjectColor = nwidgerj.DefaultObjectColor - f.ArrayColor = nwidgerj.DefaultArrayColor - f.FieldQuoteColor = nwidgerj.DefaultFieldQuoteColor - f.FieldColor = nwidgerj.DefaultFieldColor - f.StringQuoteColor = nwidgerj.DefaultStringQuoteColor - f.StringColor = nwidgerj.DefaultStringColor - f.TrueColor = nwidgerj.DefaultTrueColor - f.FalseColor = nwidgerj.DefaultFalseColor - f.NumberColor = nwidgerj.DefaultNumberColor - f.NullColor = nwidgerj.DefaultNullColor - return f -} - func makeBenchRecs() [][]interface{} { const maxRecs = 20000 recs := make([][]interface{}, 0, maxRecs) + + type someStruct struct { + i int64 + a string + } + for i := 0; i < maxRecs; i++ { rec := []interface{}{ - 1, - 3.14, - "6.77", + int(1), + int64(2), + float32(2.71), + float64(3.14), + "hello world", + someStruct{i: 8, a: "goodbye world"}, + map[string]interface{}{"a": 9, "b": "ca va"}, true, false, time.Unix(1631659220, 0),