To make more sense of the benchmark comparisons, we can use benchstat. In the BenchmarkEncode test, we specified two formats: json and binary.
func BenchmarkEncode(b *testing.B) {
b.Run("format=json", benchmarkEncodeJSON)
b.Run("format=binary", benchmarkEncodeBinary)
}
func benchmarkEncodeJSON(b *testing.B) {
var data []byte
var err error
b.ReportAllocs()
b.SetBytes(int64(len(benchmarkEvent.Message)))
for b.Loop() {
data, err = EncodeJSON(benchmarkEvent)
if err != nil {
b.Fatal(err)
}
}
sinkBytes = data
}
func benchmarkEncodeBinary(b *testing.B) {
var data []byte
b.ReportAllocs()
b.SetBytes(int64(len(benchmarkEvent.Message)))
for b.Loop() {
data = EncodeBinary(benchmarkEvent)
}
sinkBytes = data
}
func EncodeJSON(event Event) ([]byte, error) {
return json.Marshal(event)
}
func DecodeJSON(data []byte) (Event, error) {
var event Event
err := json.Unmarshal(data, &event)
return event, err
}
func EncodeBinary(event Event) []byte {
data := make([]byte, 8+len(event.Message))
binary.BigEndian.PutUint64(data[:8], event.ID)
copy(data[8:], event.Message)
return data
}
We run the benchmark test function 10 times and output the result to a file. The result is similar to the usual benchmark result; nothing new here. What’s new is the use of benchstat. Here, we provide the file to that tool with specific column and row.
The statistical summary shows that json is the baseline and shows the average values and how they differ with the binary results. The summary shows that there are significant improvements with binary encoding.
go test -run '^$' -bench '^BenchmarkEncode$' \
-count=10 > /tmp/codec01-encode.txt
benchstat -col /format -row .name /tmp/codec01-encode.txt
goos: linux
goarch: arm64
pkg: codec01
│ json │ binary │
│ sec/op │ sec/op vs base │
Encode 150.35n ± 1% 30.23n ± 3% -79.89% (p=0.000 n=10)
│ json │ binary │
│ B/s │ B/s vs base │
Encode 310.9Mi ± 1% 1545.8Mi ± 3% +397.26% (p=0.000 n=10)
│ json │ binary │
│ B/op │ B/op vs base │
Encode 104.00 ± 0% 64.00 ± 0% -38.46% (p=0.000 n=10)
│ json │ binary │
│ allocs/op │ allocs/op vs base │
Encode 2.000 ± 0% 1.000 ± 0% -50.00% (p=0.000 n=10)