Skip to content

Commit

Permalink
wip: refactoring benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
neilotoole committed Oct 3, 2021
1 parent f04c95a commit b8e39c3
Showing 1 changed file with 41 additions and 224 deletions.
265 changes: 41 additions & 224 deletions benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down

0 comments on commit b8e39c3

Please sign in to comment.