Last active
October 15, 2021 13:41
-
-
Save mjpitz/66ab3d0ecf5b4cd6776803b104876c29 to your computer and use it in GitHub Desktop.
A quick look at the performance of different encoding / serialization protocols
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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: "[email protected]", | |
}, | |
}, | |
} | |
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) | |
}) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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