Skip to content

Instantly share code, notes, and snippets.

@mjpitz
Last active October 15, 2021 13:41
Show Gist options
  • Save mjpitz/66ab3d0ecf5b4cd6776803b104876c29 to your computer and use it in GitHub Desktop.
Save mjpitz/66ab3d0ecf5b4cd6776803b104876c29 to your computer and use it in GitHub Desktop.
A quick look at the performance of different encoding / serialization protocols
package io_test
import (
"bytes"
"encoding/binary"
"encoding/hex"
"encoding/json"
"testing"
"time"
hashipack "github.com/hashicorp/go-msgpack/codec"
"github.com/stretchr/testify/require"
"github.com/vmihailenco/msgpack/v5"
"gopkg.in/yaml.v3"
)
type ContactPreferences struct{}
type Contact struct {
Preferences ContactPreferences
// one of
Phone string
Email string
}
type Person struct {
ID string
FirstName string
LastName string
ContactInfo []Contact
}
func newID() string {
data := make([]byte, 12)
now := time.Now()
binary.BigEndian.PutUint64(data[:8], uint64(now.Unix()))
binary.BigEndian.PutUint32(data[8:], uint32(now.Nanosecond()))
return hex.EncodeToString(data)
}
func harness(b *testing.B, encode func(interface{}) ([]byte, error), decode func([]byte, interface{}) error) {
decoded := &Person{
ID: newID(),
FirstName: "Alice",
ContactInfo: []Contact{
{
Phone: "555-555-5555",
},
{
Email: "alice@inwonderland.bizq",
},
},
}
encoded, err := encode(decoded)
require.NoError(b, err)
b.Run("Encode", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_, err = encode(decoded)
require.NoError(b, err)
}
})
b.Run("Decode", func(b *testing.B) {
target := &Person{}
for i := 0; i < b.N; i++ {
err = decode(encoded, target)
require.NoError(b, err)
}
})
}
func BenchmarkJSON(b *testing.B) {
harness(b, json.Marshal, json.Unmarshal)
}
func BenchmarkYAML(b *testing.B) {
harness(b, yaml.Marshal, yaml.Unmarshal)
}
func BenchmarkMSGPACK(b *testing.B) {
harness(b, msgpack.Marshal, msgpack.Unmarshal)
}
func BenchmarkHashiMSGPACK(b *testing.B) {
handle := &hashipack.MsgpackHandle{}
harness(b, func(i interface{}) ([]byte, error) {
buf := bytes.NewBuffer(nil)
enc := hashipack.NewEncoder(buf, handle)
err := enc.Encode(i)
return buf.Bytes(), err
}, func(data []byte, i interface{}) error {
return hashipack.NewDecoder(bytes.NewReader(data), handle).Decode(i)
})
}
goos: darwin
goarch: amd64
pkg: github.com/mjpitz/graphstore/internal/io
cpu: Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
BenchmarkJSON
BenchmarkJSON/Encode
BenchmarkJSON/Encode-16 1345912 898.0 ns/op
BenchmarkJSON/Decode
BenchmarkJSON/Decode-16 371601 3179 ns/op
BenchmarkYAML
BenchmarkYAML/Encode
BenchmarkYAML/Encode-16 61348 17913 ns/op
BenchmarkYAML/Decode
BenchmarkYAML/Decode-16 46744 25330 ns/op
BenchmarkMSGPACK
BenchmarkMSGPACK/Encode
BenchmarkMSGPACK/Encode-16 751675 1564 ns/op
BenchmarkMSGPACK/Decode
BenchmarkMSGPACK/Decode-16 652670 1850 ns/op
BenchmarkHashiMSGPACK
BenchmarkHashiMSGPACK/Encode
BenchmarkHashiMSGPACK/Encode-16 483379 2506 ns/op
BenchmarkHashiMSGPACK/Decode
BenchmarkHashiMSGPACK/Decode-16 456537 2611 ns/op
PASS
Process finished with exit code 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment