It’s also important to know how different sizes of data processed by the function affect benchmark matrics. In the code below, different sizes of the event message are tested. It’s expected the higher the size of the data being processed, the poorer the metrics can appear. But since we are comparing the two encoding methods, binary encoding appears better compared to JSON encoding even as the data size grows. However, at large data, they almost have the same amount of allocated heap bytes per event at 1MiB data size. It might be because they are basically doing the same amount of memory allocation, but the binary encoding is still better in a lot of marks, especially the processing speed.
func BenchmarkEncodeJSON(b *testing.B) {
for _, size := range encodingMessageSizes {
b.Run(size.name, func(b *testing.B) {
event := Event{ID: 42, Message: strings.Repeat("x", size.bytes)}
var data []byte
var err error
b.ReportAllocs()
b.SetBytes(int64(len(event.Message)))
for b.Loop() {
data, err = EncodeJSON(event)
if err != nil {
b.Fatal(err)
}
}
sinkBytes = data
})
}
}
func BenchmarkEncodeBinary(b *testing.B) {
for _, size := range encodingMessageSizes {
b.Run(size.name, func(b *testing.B) {
event := Event{ID: 42, Message: strings.Repeat("x", size.bytes)}
var data []byte
b.ReportAllocs()
b.SetBytes(int64(len(event.Message)))
for b.Loop() {
data = EncodeBinary(event)
}
sinkBytes = data
})
}
}
// Names become part of the benchmark output, for example:
// BenchmarkEncodeJSON/4KiB and BenchmarkEncodeBinary/4KiB.
var encodingMessageSizes = []struct {
name string
bytes int
}{
{name: "16B", bytes: 16},
{name: "256B", bytes: 256},
{name: "4KiB", bytes: 4 * 1024},
{name: "64KiB", bytes: 64 * 1024},
{name: "500KiB", bytes: 500 * 1024},
{name: "1MiB", bytes: 1024 * 1024},
}
In the result below, we can see that binary encoding uses less allocation resources. Binary encoding uses less bytes and less number of allocation per event.
go test -run '^$' -bench '^BenchmarkEncode'
goos: linux
goarch: arm64
pkg: codec01
BenchmarkEncodeJSON/16B-12 8947384 134.8 ns/op 118.73 MB/s 72 B/op 2 allocs/op
BenchmarkEncodeJSON/256B-12 2839560 424.5 ns/op 603.09 MB/s 312 B/op 2 allocs/op
BenchmarkEncodeJSON/4KiB-12 230463 4525 ns/op 905.18 MB/s 4891 B/op 2 allocs/op
BenchmarkEncodeJSON/64KiB-12 17946 66241 ns/op 989.36 MB/s 73908 B/op 2 allocs/op
BenchmarkEncodeJSON/500KiB-12 2280 498207 ns/op 1027.69 MB/s 528684 B/op 2 allocs/op
BenchmarkEncodeJSON/1MiB-12 1027 1118344 ns/op 937.62 MB/s 1100548 B/op 2 allocs/op
BenchmarkEncodeBinary/16B-12 61868744 20.79 ns/op 769.77 MB/s 24 B/op 1 allocs/op
BenchmarkEncodeBinary/256B-12 8737191 134.8 ns/op 1899.02 MB/s 288 B/op 1 allocs/op
BenchmarkEncodeBinary/4KiB-12 929598 1307 ns/op 3134.14 MB/s 4864 B/op 1 allocs/op
BenchmarkEncodeBinary/64KiB-12 73698 15598 ns/op 4201.69 MB/s 73728 B/op 1 allocs/op
BenchmarkEncodeBinary/500KiB-12 13584 87922 ns/op 5823.37 MB/s 516097 B/op 1 allocs/op
BenchmarkEncodeBinary/1MiB-12 7465 159647 ns/op 6568.08 MB/s 1056769 B/op 1 allocs/op
PASS
ok codec01 14.164s