diff --git a/benchmarks.go b/benchmarks.go index 90ef3d1..628cd10 100644 --- a/benchmarks.go +++ b/benchmarks.go @@ -102,6 +102,10 @@ type BenchmarkCase struct { // underlying byte slice is modified. UnsafeStringUnmarshal bool + // BufferReuseMarshal reocrds whether the serializer re-uses the + // marshalling buffer. + BufferReuseMarshal bool + // TimeSupport records the type of support time.Time values have on // this encoder. TimeSupport TimeSupport @@ -284,10 +288,11 @@ var benchmarkCases = []BenchmarkCase{ TimeSupport: TSFullTzOffset, APIKind: AKCodegen, }, { - Name: "gencode/unsafe", + Name: "gencode/unsafe_reuse", URL: "github.com/andyleap/gencode", New: gencode.NewGencodeUnsafeSerializer, + BufferReuseMarshal: true, UnsafeStringUnmarshal: true, TimeSupport: TSFullTzOffset, APIKind: AKCodegen, @@ -371,6 +376,17 @@ var benchmarkCases = []BenchmarkCase{ Notes: []string{ "time.Time values are encoded with 100 nanosecond precision.", }, + }, { + Name: "200sc/bebop/reuse", + URL: "github.com/200sc/bebop", + New: bebop200sc.NewBebop200ScReuseSerializer, + + BufferReuseMarshal: true, + TimeSupport: TSCustom, + APIKind: AKCodegen, + Notes: []string{ + "time.Time values are encoded with 100 nanosecond precision.", + }, }, { Name: "wellquite/bebop", URL: "wellquite.org/bebop", @@ -381,6 +397,17 @@ var benchmarkCases = []BenchmarkCase{ Notes: []string{ "time.Time values are encoded with 100 nanosecond precision.", }, + }, { + Name: "wellquite/bebop/reuse", + URL: "wellquite.org/bebop", + New: bebopwellquite.NewBebopWellquiteReuseSerializer, + + BufferReuseMarshal: true, + TimeSupport: TSCustom, + APIKind: AKCodegen, + Notes: []string{ + "time.Time values are encoded with 100 nanosecond precision.", + }, }, { Name: "fastjson", URL: "github.com/valyala/fastjson", @@ -388,6 +415,14 @@ var benchmarkCases = []BenchmarkCase{ TimeSupport: TSNoSupport, APIKind: AKManual, + }, { + Name: "fastjson/reuse", + URL: "github.com/valyala/fastjson", + New: fastjson.NewFastJSONReuseSerializer, + + BufferReuseMarshal: true, + TimeSupport: TSNoSupport, + APIKind: AKManual, }, { Name: "benc", URL: "github.com/deneonet/benc", @@ -411,18 +446,31 @@ var benchmarkCases = []BenchmarkCase{ TimeSupport: TSNoSupport, APIKind: AKManual, }, { - Name: "mus/unsafe", + Name: "mus/unsafe_reuse", URL: "github.com/mus-format/mus-go", New: mus.NewMUSUnsafeSerializer, - TimeSupport: TSNoSupport, - APIKind: AKManual, + BufferReuseMarshal: true, + UnsafeStringUnmarshal: true, + TimeSupport: TSNoSupport, + APIKind: AKManual, }, { Name: "baseline", URL: "", New: baseline.NewBaselineSerializer, + TimeSupport: TSNoSupport, + APIKind: AKManual, + Notes: []string{ + "This is a manually written encoding, designed to be the fastest possible for this benchmark.", + }, + }, { + Name: "baseline/unsafe_reuse", + URL: "", + New: baseline.NewBaselineUnsafeSerializer, + UnsafeStringUnmarshal: true, + BufferReuseMarshal: true, TimeSupport: TSNoSupport, APIKind: AKManual, Notes: []string{ diff --git a/genreport_test.go b/genreport_test.go index 2c60d15..aa6e988 100644 --- a/genreport_test.go +++ b/genreport_test.go @@ -22,6 +22,7 @@ type reportLine struct { UnmarshalIterCount int `json:"unmarshal_iter_count"` TotalIterCount int `json:"total_iter_count"` UnsafeStringUnmarshal bool `json:"unsafe_string_unmarshal"` + BufferReuseMarshal bool `json:"buffer_reuse_marshal"` MarshalNsOp int64 `json:"marshal_ns_op"` UnmarshalNsOp int64 `json:"unmarshal_ns_op"` TotalNsOp int64 `json:"total_ns_op"` @@ -61,6 +62,7 @@ func generateReport() error { UnmarshalNsOp: unmarshalRes.NsPerOp(), TotalNsOp: marshalRes.NsPerOp() + unmarshalRes.NsPerOp(), UnsafeStringUnmarshal: bench.UnsafeStringUnmarshal, + BufferReuseMarshal: bench.BufferReuseMarshal, SerializationSize: int64(marshalRes.Extra["B/serial"]), MarshalAllocBytes: marshalRes.AllocedBytesPerOp(), UnmarshalAllocBytes: unmarshalRes.AllocedBytesPerOp(), diff --git a/internal/serializers/baseline/baseline.go b/internal/serializers/baseline/baseline.go index 1d87803..0263868 100644 --- a/internal/serializers/baseline/baseline.go +++ b/internal/serializers/baseline/baseline.go @@ -15,9 +15,11 @@ import ( // // This is useful as an upper bound on the performance achievable for standard // marshalling/unmarshalling operations. -type BaselineSerializer struct { - b []byte -} +type BaselineSerializer struct{} + +// maxSmallStructSerializeSize is the max size of a small struct serialized +// with the baseline serializer. +const maxSmallStructSerializeSize = 8 + 8 + 4 + 1 + goserbench.MaxSmallStructPhoneSize + goserbench.MaxSmallStructNameSize // appendBool appends a bool to b. func appendBool(b []byte, v bool) []byte { @@ -39,7 +41,7 @@ func getBool(b []byte) bool { func (b *BaselineSerializer) Marshal(o interface{}) ([]byte, error) { a := o.(*goserbench.SmallStruct) - buf := b.b[:0] + buf := make([]byte, 0, maxSmallStructSerializeSize) buf = binary.LittleEndian.AppendUint64(buf, uint64(a.BirthDay.UnixNano())) buf = binary.LittleEndian.AppendUint64(buf, math.Float64bits(a.Money)) buf = binary.LittleEndian.AppendUint32(buf, uint32(a.Siblings)) @@ -50,6 +52,39 @@ func (b *BaselineSerializer) Marshal(o interface{}) ([]byte, error) { } func (b *BaselineSerializer) Unmarshal(d []byte, o interface{}) error { + a := o.(*goserbench.SmallStruct) + a.BirthDay = time.Unix(0, int64(binary.LittleEndian.Uint64(d[:8]))) + a.Money = math.Float64frombits(binary.LittleEndian.Uint64(d[8:16])) + a.Siblings = int(binary.LittleEndian.Uint32(d[16:20])) + a.Name = string(d[20:36]) + a.Phone = string(d[36:46]) + a.Spouse = getBool(d[46:]) + return nil +} + +func NewBaselineSerializer() goserbench.Serializer { + return &BaselineSerializer{} +} + +// BaselineUnsafeSerializer is similar to BaselizeSerializer, but it reuses +// the marshalling buffer and unmarshals unsafe strings. +type BaselineUnsafeSerializer struct { + buf []byte +} + +func (b *BaselineUnsafeSerializer) Marshal(o interface{}) ([]byte, error) { + a := o.(*goserbench.SmallStruct) + buf := b.buf + buf = binary.LittleEndian.AppendUint64(buf, uint64(a.BirthDay.UnixNano())) + buf = binary.LittleEndian.AppendUint64(buf, math.Float64bits(a.Money)) + buf = binary.LittleEndian.AppendUint32(buf, uint32(a.Siblings)) + buf = append(buf, []byte(a.Name)...) + buf = append(buf, []byte(a.Phone)...) + buf = appendBool(buf, a.Spouse) + return buf, nil +} + +func (b *BaselineUnsafeSerializer) Unmarshal(d []byte, o interface{}) error { a := o.(*goserbench.SmallStruct) a.BirthDay = time.Unix(0, int64(binary.LittleEndian.Uint64(d[:8]))) a.Money = math.Float64frombits(binary.LittleEndian.Uint64(d[8:16])) @@ -61,6 +96,8 @@ func (b *BaselineSerializer) Unmarshal(d []byte, o interface{}) error { return nil } -func NewBaselineSerializer() goserbench.Serializer { - return &BaselineSerializer{b: make([]byte, 47)} +func NewBaselineUnsafeSerializer() goserbench.Serializer { + return &BaselineUnsafeSerializer{ + buf: make([]byte, 0, maxSmallStructSerializeSize), + } } diff --git a/internal/serializers/bebop_200sc/bebop_200sc.go b/internal/serializers/bebop_200sc/bebop_200sc.go index d3d917a..9ed2725 100644 --- a/internal/serializers/bebop_200sc/bebop_200sc.go +++ b/internal/serializers/bebop_200sc/bebop_200sc.go @@ -20,6 +20,9 @@ func (s *Bebop200ScSerializer) Marshal(o interface{}) (buf []byte, err error) { a.Siblings = int32(v.Siblings) a.Spouse = v.Spouse a.Money = v.Money + if s.buf == nil { + return a.MarshalBebop(), nil + } n := a.MarshalBebopTo(s.buf) return s.buf[:n], nil } @@ -50,5 +53,9 @@ func (s *Bebop200ScSerializer) ForceUTC() bool { } func NewBebop200ScSerializer() goserbench.Serializer { + return &Bebop200ScSerializer{} +} + +func NewBebop200ScReuseSerializer() goserbench.Serializer { return &Bebop200ScSerializer{buf: make([]byte, 1024)} } diff --git a/internal/serializers/bebop_wellquite/bebop_wellquite.go b/internal/serializers/bebop_wellquite/bebop_wellquite.go index 42ac8a0..3466684 100644 --- a/internal/serializers/bebop_wellquite/bebop_wellquite.go +++ b/internal/serializers/bebop_wellquite/bebop_wellquite.go @@ -45,6 +45,10 @@ func (s *BebopWellquiteSerializer) TimePrecision() time.Duration { } func NewBebopWellquiteSerializer() goserbench.Serializer { + return &BebopWellquiteSerializer{} +} + +func NewBebopWellquiteReuseSerializer() goserbench.Serializer { return &BebopWellquiteSerializer{ buf: make([]byte, 1024), } diff --git a/internal/serializers/fastjson/fastjson.go b/internal/serializers/fastjson/fastjson.go index 7ef2b5e..76fd86f 100644 --- a/internal/serializers/fastjson/fastjson.go +++ b/internal/serializers/fastjson/fastjson.go @@ -47,10 +47,19 @@ func (s *FastJSONSerializer) Unmarshal(bs []byte, o interface{}) (err error) { } func NewFastJSONSerializer() goserbench.Serializer { + var arena fastjson.Arena + return &FastJSONSerializer{ + object: arena.NewObject(), + arena: arena, + } +} + +func NewFastJSONReuseSerializer() goserbench.Serializer { var arena fastjson.Arena return &FastJSONSerializer{ object: arena.NewObject(), arena: arena, buf: make([]byte, 0, 1024), } + } diff --git a/internal/serializers/gencode/gencode.go b/internal/serializers/gencode/gencode.go index 94444cf..a42a4c2 100644 --- a/internal/serializers/gencode/gencode.go +++ b/internal/serializers/gencode/gencode.go @@ -7,8 +7,7 @@ import ( ) type GencodeSerializer struct { - buf []byte - a GencodeA + a GencodeA } func (s *GencodeSerializer) Marshal(o interface{}) ([]byte, error) { @@ -20,7 +19,7 @@ func (s *GencodeSerializer) Marshal(o interface{}) ([]byte, error) { a.Siblings = int32(v.Siblings) a.Spouse = v.Spouse a.Money = v.Money - return a.Marshal(s.buf) + return a.Marshal(nil) } func (s *GencodeSerializer) Unmarshal(bs []byte, o interface{}) (err error) { @@ -41,7 +40,7 @@ func (s *GencodeSerializer) Unmarshal(bs []byte, o interface{}) (err error) { } func NewGencodeSerializer() goserbench.Serializer { - return &GencodeSerializer{buf: make([]byte, 0, 1024)} + return &GencodeSerializer{} } type GencodeUnsafeSerializer struct { diff --git a/internal/serializers/mus/mus.go b/internal/serializers/mus/mus.go index 364b72d..2c13d6a 100644 --- a/internal/serializers/mus/mus.go +++ b/internal/serializers/mus/mus.go @@ -73,7 +73,9 @@ func NewMUSSerializer() goserbench.Serializer { return MUSSerializer{} } -type MUSUnsafeSerializer struct{} +type MUSUnsafeSerializer struct { + buf []byte +} func (s MUSUnsafeSerializer) Marshal(o interface{}) ([]byte, error) { v := o.(*goserbench.SmallStruct) @@ -83,7 +85,7 @@ func (s MUSUnsafeSerializer) Marshal(o interface{}) ([]byte, error) { n += unsafe.SizeInt32(int32(v.Siblings)) n += unsafe.SizeBool(v.Spouse) n += unsafe.SizeFloat64(v.Money) - buf := make([]byte, n) + buf := s.buf[:n] n = unsafe.MarshalString(v.Name, buf) n += unsafe.MarshalInt64(v.BirthDay.UnixNano(), buf[n:]) n += unsafe.MarshalString(v.Phone, buf[n:]) @@ -132,5 +134,5 @@ func (s MUSUnsafeSerializer) Unmarshal(bs []byte, o interface{}) (err error) { } func NewMUSUnsafeSerializer() goserbench.Serializer { - return MUSUnsafeSerializer{} + return MUSUnsafeSerializer{buf: make([]byte, 1024)} } diff --git a/report/data.js b/report/data.js index cdd6372..cc0dfe1 100644 --- a/report/data.js +++ b/report/data.js @@ -1,13 +1,14 @@ var data = [ { "name": "gotiny", - "marshal_iter_count": 2246960, - "unmarshal_iter_count": 6504465, - "total_iter_count": 8751425, + "marshal_iter_count": 2824863, + "unmarshal_iter_count": 6697485, + "total_iter_count": 9522348, "unsafe_string_unmarshal": false, - "marshal_ns_op": 450, - "unmarshal_ns_op": 176, - "total_ns_op": 626, + "buffer_reuse_marshal": false, + "marshal_ns_op": 425, + "unmarshal_ns_op": 174, + "total_ns_op": 599, "serialization_size": 47, "marshal_alloc_bytes": 168, "unmarshal_alloc_bytes": 32, @@ -22,13 +23,14 @@ var data = [ }, { "name": "msgp", - "marshal_iter_count": 8065608, - "unmarshal_iter_count": 5599303, - "total_iter_count": 13664911, + "marshal_iter_count": 8127158, + "unmarshal_iter_count": 5665038, + "total_iter_count": 13792196, "unsafe_string_unmarshal": false, + "buffer_reuse_marshal": false, "marshal_ns_op": 143, - "unmarshal_ns_op": 215, - "total_ns_op": 358, + "unmarshal_ns_op": 216, + "total_ns_op": 359, "serialization_size": 97, "marshal_alloc_bytes": 128, "unmarshal_alloc_bytes": 32, @@ -43,13 +45,14 @@ var data = [ }, { "name": "msgpack", - "marshal_iter_count": 1210009, + "marshal_iter_count": 1000000, "unmarshal_iter_count": 1000000, - "total_iter_count": 2210009, + "total_iter_count": 2000000, "unsafe_string_unmarshal": false, - "marshal_ns_op": 992, - "unmarshal_ns_op": 1240, - "total_ns_op": 2232, + "buffer_reuse_marshal": false, + "marshal_ns_op": 1012, + "unmarshal_ns_op": 1219, + "total_ns_op": 2231, "serialization_size": 92, "marshal_alloc_bytes": 264, "unmarshal_alloc_bytes": 80, @@ -64,13 +67,14 @@ var data = [ }, { "name": "json", - "marshal_iter_count": 811616, - "unmarshal_iter_count": 325716, - "total_iter_count": 1137332, + "marshal_iter_count": 830055, + "unmarshal_iter_count": 342466, + "total_iter_count": 1172521, "unsafe_string_unmarshal": false, - "marshal_ns_op": 1447, - "unmarshal_ns_op": 3541, - "total_ns_op": 4988, + "buffer_reuse_marshal": false, + "marshal_ns_op": 1424, + "unmarshal_ns_op": 3498, + "total_ns_op": 4922, "serialization_size": 151, "marshal_alloc_bytes": 208, "unmarshal_alloc_bytes": 248, @@ -85,13 +89,14 @@ var data = [ }, { "name": "jsoniter", - "marshal_iter_count": 1297754, - "unmarshal_iter_count": 929462, - "total_iter_count": 2227216, + "marshal_iter_count": 1272920, + "unmarshal_iter_count": 896574, + "total_iter_count": 2169494, "unsafe_string_unmarshal": false, - "marshal_ns_op": 918, - "unmarshal_ns_op": 1307, - "total_ns_op": 2225, + "buffer_reuse_marshal": false, + "marshal_ns_op": 951, + "unmarshal_ns_op": 1313, + "total_ns_op": 2264, "serialization_size": 141, "marshal_alloc_bytes": 200, "unmarshal_alloc_bytes": 136, @@ -106,13 +111,14 @@ var data = [ }, { "name": "easyjson", - "marshal_iter_count": 965746, + "marshal_iter_count": 1000000, "unmarshal_iter_count": 1000000, - "total_iter_count": 1965746, + "total_iter_count": 2000000, "unsafe_string_unmarshal": false, - "marshal_ns_op": 1176, - "unmarshal_ns_op": 1073, - "total_ns_op": 2249, + "buffer_reuse_marshal": false, + "marshal_ns_op": 1130, + "unmarshal_ns_op": 1058, + "total_ns_op": 2188, "serialization_size": 151, "marshal_alloc_bytes": 976, "unmarshal_alloc_bytes": 32, @@ -127,13 +133,14 @@ var data = [ }, { "name": "bson", - "marshal_iter_count": 375661, - "unmarshal_iter_count": 627021, - "total_iter_count": 1002682, + "marshal_iter_count": 911517, + "unmarshal_iter_count": 624112, + "total_iter_count": 1535629, "unsafe_string_unmarshal": false, - "marshal_ns_op": 2766, - "unmarshal_ns_op": 1921, - "total_ns_op": 4687, + "buffer_reuse_marshal": false, + "marshal_ns_op": 1135, + "unmarshal_ns_op": 1920, + "total_ns_op": 3055, "serialization_size": 110, "marshal_alloc_bytes": 376, "unmarshal_alloc_bytes": 144, @@ -148,13 +155,14 @@ var data = [ }, { "name": "mongobson", - "marshal_iter_count": 709714, - "unmarshal_iter_count": 616824, - "total_iter_count": 1326538, + "marshal_iter_count": 678462, + "unmarshal_iter_count": 599133, + "total_iter_count": 1277595, "unsafe_string_unmarshal": false, - "marshal_ns_op": 1637, - "unmarshal_ns_op": 1857, - "total_ns_op": 3494, + "buffer_reuse_marshal": false, + "marshal_ns_op": 1644, + "unmarshal_ns_op": 1851, + "total_ns_op": 3495, "serialization_size": 110, "marshal_alloc_bytes": 240, "unmarshal_alloc_bytes": 328, @@ -169,13 +177,14 @@ var data = [ }, { "name": "gob", - "marshal_iter_count": 196543, - "unmarshal_iter_count": 40824, - "total_iter_count": 237367, + "marshal_iter_count": 199690, + "unmarshal_iter_count": 41342, + "total_iter_count": 241032, "unsafe_string_unmarshal": false, - "marshal_ns_op": 5930, - "unmarshal_ns_op": 29622, - "total_ns_op": 35552, + "buffer_reuse_marshal": false, + "marshal_ns_op": 5978, + "unmarshal_ns_op": 29124, + "total_ns_op": 35102, "serialization_size": 172, "marshal_alloc_bytes": 1744, "unmarshal_alloc_bytes": 7656, @@ -190,17 +199,18 @@ var data = [ }, { "name": "davecgh/xdr", - "marshal_iter_count": 752708, + "marshal_iter_count": 717974, "unmarshal_iter_count": 1000000, - "total_iter_count": 1752708, + "total_iter_count": 1717974, "unsafe_string_unmarshal": false, - "marshal_ns_op": 1558, - "unmarshal_ns_op": 1191, - "total_ns_op": 2749, + "buffer_reuse_marshal": false, + "marshal_ns_op": 1561, + "unmarshal_ns_op": 1224, + "total_ns_op": 2785, "serialization_size": 92, "marshal_alloc_bytes": 392, - "unmarshal_alloc_bytes": 151, - "total_alloc_bytes": 543, + "unmarshal_alloc_bytes": 152, + "total_alloc_bytes": 544, "marshal_allocs": 20, "unmarshal_allocs": 10, "total_allocs": 30, @@ -212,12 +222,13 @@ var data = [ { "name": "ugorji/msgpack", "marshal_iter_count": 1000000, - "unmarshal_iter_count": 928220, - "total_iter_count": 1928220, + "unmarshal_iter_count": 930351, + "total_iter_count": 1930351, "unsafe_string_unmarshal": false, - "marshal_ns_op": 1073, - "unmarshal_ns_op": 1226, - "total_ns_op": 2299, + "buffer_reuse_marshal": false, + "marshal_ns_op": 1046, + "unmarshal_ns_op": 1228, + "total_ns_op": 2274, "serialization_size": 91, "marshal_alloc_bytes": 1240, "unmarshal_alloc_bytes": 608, @@ -232,14 +243,15 @@ var data = [ }, { "name": "ugorji/binc", - "marshal_iter_count": 947761, + "marshal_iter_count": 996676, "unmarshal_iter_count": 1000000, - "total_iter_count": 1947761, + "total_iter_count": 1996676, "unsafe_string_unmarshal": false, - "marshal_ns_op": 1220, - "unmarshal_ns_op": 1128, - "total_ns_op": 2348, - "serialization_size": 94, + "buffer_reuse_marshal": false, + "marshal_ns_op": 1145, + "unmarshal_ns_op": 1140, + "total_ns_op": 2285, + "serialization_size": 95, "marshal_alloc_bytes": 1256, "unmarshal_alloc_bytes": 672, "total_alloc_bytes": 1928, @@ -253,13 +265,14 @@ var data = [ }, { "name": "sereal", - "marshal_iter_count": 345529, - "unmarshal_iter_count": 357453, - "total_iter_count": 702982, + "marshal_iter_count": 361704, + "unmarshal_iter_count": 359160, + "total_iter_count": 720864, "unsafe_string_unmarshal": false, - "marshal_ns_op": 3147, - "unmarshal_ns_op": 3038, - "total_ns_op": 6185, + "buffer_reuse_marshal": false, + "marshal_ns_op": 3124, + "unmarshal_ns_op": 3068, + "total_ns_op": 6192, "serialization_size": 142, "marshal_alloc_bytes": 1104, "unmarshal_alloc_bytes": 896, @@ -274,13 +287,14 @@ var data = [ }, { "name": "alecthomas/binary", - "marshal_iter_count": 613990, - "unmarshal_iter_count": 845469, - "total_iter_count": 1459459, + "marshal_iter_count": 674114, + "unmarshal_iter_count": 890947, + "total_iter_count": 1565061, "unsafe_string_unmarshal": false, - "marshal_ns_op": 1722, - "unmarshal_ns_op": 1388, - "total_ns_op": 3110, + "buffer_reuse_marshal": false, + "marshal_ns_op": 1739, + "unmarshal_ns_op": 1363, + "total_ns_op": 3102, "serialization_size": 61, "marshal_alloc_bytes": 360, "unmarshal_alloc_bytes": 240, @@ -295,13 +309,14 @@ var data = [ }, { "name": "flatbuffers", - "marshal_iter_count": 1486569, - "unmarshal_iter_count": 7354107, - "total_iter_count": 8840676, + "marshal_iter_count": 1455066, + "unmarshal_iter_count": 7601462, + "total_iter_count": 9056528, "unsafe_string_unmarshal": false, - "marshal_ns_op": 803, - "unmarshal_ns_op": 163, - "total_ns_op": 966, + "buffer_reuse_marshal": false, + "marshal_ns_op": 825, + "unmarshal_ns_op": 160, + "total_ns_op": 985, "serialization_size": 95, "marshal_alloc_bytes": 376, "unmarshal_alloc_bytes": 32, @@ -316,13 +331,14 @@ var data = [ }, { "name": "capnproto", - "marshal_iter_count": 424782, - "unmarshal_iter_count": 2838612, - "total_iter_count": 3263394, + "marshal_iter_count": 448254, + "unmarshal_iter_count": 2924187, + "total_iter_count": 3372441, "unsafe_string_unmarshal": false, - "marshal_ns_op": 2430, - "unmarshal_ns_op": 421, - "total_ns_op": 2851, + "buffer_reuse_marshal": false, + "marshal_ns_op": 2252, + "unmarshal_ns_op": 418, + "total_ns_op": 2670, "serialization_size": 96, "marshal_alloc_bytes": 4392, "unmarshal_alloc_bytes": 112, @@ -341,13 +357,14 @@ var data = [ "unmarshal_iter_count": 1000000, "total_iter_count": 2000000, "unsafe_string_unmarshal": false, - "marshal_ns_op": 1748, - "unmarshal_ns_op": 1613, - "total_ns_op": 3361, + "buffer_reuse_marshal": false, + "marshal_ns_op": 2131, + "unmarshal_ns_op": 1871, + "total_ns_op": 4002, "serialization_size": 85, "marshal_alloc_bytes": 412, - "unmarshal_alloc_bytes": 223, - "total_alloc_bytes": 635, + "unmarshal_alloc_bytes": 224, + "total_alloc_bytes": 636, "marshal_allocs": 8, "unmarshal_allocs": 9, "total_allocs": 17, @@ -358,13 +375,14 @@ var data = [ }, { "name": "hprose2", - "marshal_iter_count": 2844640, - "unmarshal_iter_count": 2436789, - "total_iter_count": 5281429, + "marshal_iter_count": 2842987, + "unmarshal_iter_count": 2536797, + "total_iter_count": 5379784, "unsafe_string_unmarshal": false, - "marshal_ns_op": 428, - "unmarshal_ns_op": 486, - "total_ns_op": 914, + "buffer_reuse_marshal": false, + "marshal_ns_op": 419, + "unmarshal_ns_op": 525, + "total_ns_op": 944, "serialization_size": 85, "marshal_alloc_bytes": 0, "unmarshal_alloc_bytes": 56, @@ -379,13 +397,14 @@ var data = [ }, { "name": "dedis/protobuf", - "marshal_iter_count": 1638974, - "unmarshal_iter_count": 1236328, - "total_iter_count": 2875302, + "marshal_iter_count": 1596147, + "unmarshal_iter_count": 1269361, + "total_iter_count": 2865508, "unsafe_string_unmarshal": false, - "marshal_ns_op": 723, - "unmarshal_ns_op": 960, - "total_ns_op": 1683, + "buffer_reuse_marshal": false, + "marshal_ns_op": 751, + "unmarshal_ns_op": 946, + "total_ns_op": 1697, "serialization_size": 52, "marshal_alloc_bytes": 144, "unmarshal_alloc_bytes": 104, @@ -400,13 +419,14 @@ var data = [ }, { "name": "pulsar", - "marshal_iter_count": 2002485, - "unmarshal_iter_count": 2233466, - "total_iter_count": 4235951, + "marshal_iter_count": 2043909, + "unmarshal_iter_count": 2230825, + "total_iter_count": 4274734, "unsafe_string_unmarshal": false, - "marshal_ns_op": 586, + "buffer_reuse_marshal": false, + "marshal_ns_op": 591, "unmarshal_ns_op": 542, - "total_ns_op": 1128, + "total_ns_op": 1133, "serialization_size": 51, "marshal_alloc_bytes": 304, "unmarshal_alloc_bytes": 160, @@ -421,13 +441,14 @@ var data = [ }, { "name": "gogo/protobuf", - "marshal_iter_count": 9642632, - "unmarshal_iter_count": 6536440, - "total_iter_count": 16179072, + "marshal_iter_count": 9495188, + "unmarshal_iter_count": 7050087, + "total_iter_count": 16545275, "unsafe_string_unmarshal": false, - "marshal_ns_op": 121, - "unmarshal_ns_op": 175, - "total_ns_op": 296, + "buffer_reuse_marshal": false, + "marshal_ns_op": 124, + "unmarshal_ns_op": 173, + "total_ns_op": 297, "serialization_size": 53, "marshal_alloc_bytes": 64, "unmarshal_alloc_bytes": 32, @@ -442,20 +463,21 @@ var data = [ }, { "name": "gogo/jsonpb", - "marshal_iter_count": 96399, - "unmarshal_iter_count": 76960, - "total_iter_count": 173359, + "marshal_iter_count": 95270, + "unmarshal_iter_count": 75685, + "total_iter_count": 170955, "unsafe_string_unmarshal": false, - "marshal_ns_op": 12081, - "unmarshal_ns_op": 15879, - "total_ns_op": 27960, + "buffer_reuse_marshal": false, + "marshal_ns_op": 12204, + "unmarshal_ns_op": 16011, + "total_ns_op": 28215, "serialization_size": 125, - "marshal_alloc_bytes": 2757, - "unmarshal_alloc_bytes": 3161, - "total_alloc_bytes": 5918, + "marshal_alloc_bytes": 2747, + "unmarshal_alloc_bytes": 3151, + "total_alloc_bytes": 5898, "marshal_allocs": 80, - "unmarshal_allocs": 55, - "total_allocs": 135, + "unmarshal_allocs": 54, + "total_allocs": 134, "time_support": "RFC3339ns", "api_kind": "codegen", "url": "github.com/gogo/protobuf/proto", @@ -463,13 +485,14 @@ var data = [ }, { "name": "colfer", - "marshal_iter_count": 9149020, - "unmarshal_iter_count": 8591299, - "total_iter_count": 17740319, + "marshal_iter_count": 9157371, + "unmarshal_iter_count": 8785465, + "total_iter_count": 17942836, "unsafe_string_unmarshal": false, - "marshal_ns_op": 132, - "unmarshal_ns_op": 140, - "total_ns_op": 272, + "buffer_reuse_marshal": false, + "marshal_ns_op": 128, + "unmarshal_ns_op": 138, + "total_ns_op": 266, "serialization_size": 51, "marshal_alloc_bytes": 64, "unmarshal_alloc_bytes": 32, @@ -484,34 +507,36 @@ var data = [ }, { "name": "gencode", - "marshal_iter_count": 10810418, - "unmarshal_iter_count": 8970657, - "total_iter_count": 19781075, + "marshal_iter_count": 7721150, + "unmarshal_iter_count": 9337818, + "total_iter_count": 17058968, "unsafe_string_unmarshal": false, - "marshal_ns_op": 107, - "unmarshal_ns_op": 131, - "total_ns_op": 238, + "buffer_reuse_marshal": false, + "marshal_ns_op": 153, + "unmarshal_ns_op": 129, + "total_ns_op": 282, "serialization_size": 53, - "marshal_alloc_bytes": 16, + "marshal_alloc_bytes": 80, "unmarshal_alloc_bytes": 32, - "total_alloc_bytes": 48, - "marshal_allocs": 1, + "total_alloc_bytes": 112, + "marshal_allocs": 2, "unmarshal_allocs": 2, - "total_allocs": 3, + "total_allocs": 4, "time_support": "fulltzoffset", "api_kind": "codegen", "url": "github.com/andyleap/gencode", "notes": "" }, { - "name": "gencode/unsafe", - "marshal_iter_count": 25375959, - "unmarshal_iter_count": 10561101, - "total_iter_count": 35937060, + "name": "gencode/unsafe_reuse", + "marshal_iter_count": 25454443, + "unmarshal_iter_count": 10747903, + "total_iter_count": 36202346, "unsafe_string_unmarshal": true, - "marshal_ns_op": 47, - "unmarshal_ns_op": 113, - "total_ns_op": 160, + "buffer_reuse_marshal": true, + "marshal_ns_op": 49, + "unmarshal_ns_op": 112, + "total_ns_op": 161, "serialization_size": 46, "marshal_alloc_bytes": 0, "unmarshal_alloc_bytes": 32, @@ -526,13 +551,14 @@ var data = [ }, { "name": "calmh/xdr", - "marshal_iter_count": 7565384, - "unmarshal_iter_count": 8036689, - "total_iter_count": 15602073, + "marshal_iter_count": 7591645, + "unmarshal_iter_count": 8884662, + "total_iter_count": 16476307, "unsafe_string_unmarshal": false, - "marshal_ns_op": 154, - "unmarshal_ns_op": 150, - "total_ns_op": 304, + "buffer_reuse_marshal": false, + "marshal_ns_op": 159, + "unmarshal_ns_op": 137, + "total_ns_op": 296, "serialization_size": 60, "marshal_alloc_bytes": 64, "unmarshal_alloc_bytes": 32, @@ -547,13 +573,14 @@ var data = [ }, { "name": "goavro", - "marshal_iter_count": 558049, - "unmarshal_iter_count": 219433, - "total_iter_count": 777482, + "marshal_iter_count": 563248, + "unmarshal_iter_count": 217836, + "total_iter_count": 781084, "unsafe_string_unmarshal": false, - "marshal_ns_op": 2129, - "unmarshal_ns_op": 5215, - "total_ns_op": 7344, + "buffer_reuse_marshal": false, + "marshal_ns_op": 2137, + "unmarshal_ns_op": 5183, + "total_ns_op": 7320, "serialization_size": 47, "marshal_alloc_bytes": 584, "unmarshal_alloc_bytes": 2232, @@ -568,13 +595,14 @@ var data = [ }, { "name": "avro2/text", - "marshal_iter_count": 362406, - "unmarshal_iter_count": 364477, - "total_iter_count": 726883, + "marshal_iter_count": 343981, + "unmarshal_iter_count": 382122, + "total_iter_count": 726103, "unsafe_string_unmarshal": false, + "buffer_reuse_marshal": false, "marshal_ns_op": 3282, - "unmarshal_ns_op": 3169, - "total_ns_op": 6451, + "unmarshal_ns_op": 3120, + "total_ns_op": 6402, "serialization_size": 133, "marshal_alloc_bytes": 1320, "unmarshal_alloc_bytes": 656, @@ -589,13 +617,14 @@ var data = [ }, { "name": "avro2/binary", - "marshal_iter_count": 1246824, - "unmarshal_iter_count": 1221428, - "total_iter_count": 2468252, + "marshal_iter_count": 1242313, + "unmarshal_iter_count": 1218283, + "total_iter_count": 2460596, "unsafe_string_unmarshal": false, - "marshal_ns_op": 959, - "unmarshal_ns_op": 978, - "total_ns_op": 1937, + "buffer_reuse_marshal": false, + "marshal_ns_op": 964, + "unmarshal_ns_op": 977, + "total_ns_op": 1941, "serialization_size": 47, "marshal_alloc_bytes": 464, "unmarshal_alloc_bytes": 464, @@ -610,13 +639,14 @@ var data = [ }, { "name": "ikea", - "marshal_iter_count": 1947909, - "unmarshal_iter_count": 1653921, - "total_iter_count": 3601830, + "marshal_iter_count": 2012862, + "unmarshal_iter_count": 1659099, + "total_iter_count": 3671961, "unsafe_string_unmarshal": false, - "marshal_ns_op": 615, - "unmarshal_ns_op": 731, - "total_ns_op": 1346, + "buffer_reuse_marshal": false, + "marshal_ns_op": 602, + "unmarshal_ns_op": 724, + "total_ns_op": 1326, "serialization_size": 55, "marshal_alloc_bytes": 72, "unmarshal_alloc_bytes": 96, @@ -631,13 +661,14 @@ var data = [ }, { "name": "shamaton/msgpack/map", - "marshal_iter_count": 1571336, - "unmarshal_iter_count": 1707856, - "total_iter_count": 3279192, + "marshal_iter_count": 1580954, + "unmarshal_iter_count": 1761334, + "total_iter_count": 3342288, "unsafe_string_unmarshal": false, - "marshal_ns_op": 761, - "unmarshal_ns_op": 706, - "total_ns_op": 1467, + "buffer_reuse_marshal": false, + "marshal_ns_op": 759, + "unmarshal_ns_op": 681, + "total_ns_op": 1440, "serialization_size": 92, "marshal_alloc_bytes": 192, "unmarshal_alloc_bytes": 88, @@ -652,13 +683,14 @@ var data = [ }, { "name": "shamaton/msgpack/array", - "marshal_iter_count": 1828490, - "unmarshal_iter_count": 2181315, - "total_iter_count": 4009805, + "marshal_iter_count": 1844930, + "unmarshal_iter_count": 2255613, + "total_iter_count": 4100543, "unsafe_string_unmarshal": false, - "marshal_ns_op": 657, - "unmarshal_ns_op": 551, - "total_ns_op": 1208, + "buffer_reuse_marshal": false, + "marshal_ns_op": 643, + "unmarshal_ns_op": 533, + "total_ns_op": 1176, "serialization_size": 50, "marshal_alloc_bytes": 160, "unmarshal_alloc_bytes": 88, @@ -673,13 +705,14 @@ var data = [ }, { "name": "shamaton/msgpackgen/map", - "marshal_iter_count": 4443798, - "unmarshal_iter_count": 3049044, - "total_iter_count": 7492842, + "marshal_iter_count": 4475046, + "unmarshal_iter_count": 3054723, + "total_iter_count": 7529769, "unsafe_string_unmarshal": false, - "marshal_ns_op": 265, - "unmarshal_ns_op": 394, - "total_ns_op": 659, + "buffer_reuse_marshal": false, + "marshal_ns_op": 266, + "unmarshal_ns_op": 391, + "total_ns_op": 657, "serialization_size": 92, "marshal_alloc_bytes": 176, "unmarshal_alloc_bytes": 112, @@ -694,13 +727,14 @@ var data = [ }, { "name": "shamaton/msgpackgen/array", - "marshal_iter_count": 5223513, - "unmarshal_iter_count": 4951287, - "total_iter_count": 10174800, + "marshal_iter_count": 5258248, + "unmarshal_iter_count": 4806144, + "total_iter_count": 10064392, "unsafe_string_unmarshal": false, - "marshal_ns_op": 226, - "unmarshal_ns_op": 244, - "total_ns_op": 470, + "buffer_reuse_marshal": false, + "marshal_ns_op": 222, + "unmarshal_ns_op": 243, + "total_ns_op": 465, "serialization_size": 50, "marshal_alloc_bytes": 144, "unmarshal_alloc_bytes": 112, @@ -715,13 +749,14 @@ var data = [ }, { "name": "ssz", - "marshal_iter_count": 296910, - "unmarshal_iter_count": 422118, - "total_iter_count": 719028, + "marshal_iter_count": 304688, + "unmarshal_iter_count": 424064, + "total_iter_count": 728752, "unsafe_string_unmarshal": false, - "marshal_ns_op": 3871, - "unmarshal_ns_op": 2682, - "total_ns_op": 6553, + "buffer_reuse_marshal": false, + "marshal_ns_op": 3689, + "unmarshal_ns_op": 2676, + "total_ns_op": 6365, "serialization_size": 55, "marshal_alloc_bytes": 416, "unmarshal_alloc_bytes": 264, @@ -736,13 +771,36 @@ var data = [ }, { "name": "200sc/bebop", - "marshal_iter_count": 25525424, - "unmarshal_iter_count": 10196658, - "total_iter_count": 35722082, + "marshal_iter_count": 12309823, + "unmarshal_iter_count": 9987800, + "total_iter_count": 22297623, "unsafe_string_unmarshal": false, + "buffer_reuse_marshal": false, + "marshal_ns_op": 95, + "unmarshal_ns_op": 115, + "total_ns_op": 210, + "serialization_size": 55, + "marshal_alloc_bytes": 64, + "unmarshal_alloc_bytes": 32, + "total_alloc_bytes": 96, + "marshal_allocs": 1, + "unmarshal_allocs": 2, + "total_allocs": 3, + "time_support": "custom", + "api_kind": "codegen", + "url": "github.com/200sc/bebop", + "notes": "time.Time values are encoded with 100 nanosecond precision." + }, + { + "name": "200sc/bebop/reuse", + "marshal_iter_count": 26019288, + "unmarshal_iter_count": 10439342, + "total_iter_count": 36458630, + "unsafe_string_unmarshal": false, + "buffer_reuse_marshal": true, "marshal_ns_op": 48, - "unmarshal_ns_op": 116, - "total_ns_op": 164, + "unmarshal_ns_op": 115, + "total_ns_op": 163, "serialization_size": 55, "marshal_alloc_bytes": 0, "unmarshal_alloc_bytes": 32, @@ -757,12 +815,35 @@ var data = [ }, { "name": "wellquite/bebop", - "marshal_iter_count": 22999501, - "unmarshal_iter_count": 9357578, - "total_iter_count": 32357079, + "marshal_iter_count": 11484367, + "unmarshal_iter_count": 8776882, + "total_iter_count": 20261249, + "unsafe_string_unmarshal": false, + "buffer_reuse_marshal": false, + "marshal_ns_op": 98, + "unmarshal_ns_op": 132, + "total_ns_op": 230, + "serialization_size": 55, + "marshal_alloc_bytes": 64, + "unmarshal_alloc_bytes": 32, + "total_alloc_bytes": 96, + "marshal_allocs": 1, + "unmarshal_allocs": 2, + "total_allocs": 3, + "time_support": "custom", + "api_kind": "codegen", + "url": "wellquite.org/bebop", + "notes": "time.Time values are encoded with 100 nanosecond precision." + }, + { + "name": "wellquite/bebop/reuse", + "marshal_iter_count": 22968068, + "unmarshal_iter_count": 9026935, + "total_iter_count": 31995003, "unsafe_string_unmarshal": false, - "marshal_ns_op": 55, - "unmarshal_ns_op": 127, + "buffer_reuse_marshal": true, + "marshal_ns_op": 52, + "unmarshal_ns_op": 130, "total_ns_op": 182, "serialization_size": 55, "marshal_alloc_bytes": 0, @@ -778,13 +859,36 @@ var data = [ }, { "name": "fastjson", - "marshal_iter_count": 698758, - "unmarshal_iter_count": 468676, - "total_iter_count": 1167434, + "marshal_iter_count": 558775, + "unmarshal_iter_count": 533956, + "total_iter_count": 1092731, "unsafe_string_unmarshal": false, - "marshal_ns_op": 1644, - "unmarshal_ns_op": 2189, - "total_ns_op": 3833, + "buffer_reuse_marshal": false, + "marshal_ns_op": 2038, + "unmarshal_ns_op": 2104, + "total_ns_op": 4142, + "serialization_size": 133, + "marshal_alloc_bytes": 1864, + "unmarshal_alloc_bytes": 1800, + "total_alloc_bytes": 3664, + "marshal_allocs": 13, + "unmarshal_allocs": 11, + "total_allocs": 24, + "time_support": "no", + "api_kind": "manual", + "url": "github.com/valyala/fastjson", + "notes": "" + }, + { + "name": "fastjson/reuse", + "marshal_iter_count": 715246, + "unmarshal_iter_count": 510781, + "total_iter_count": 1226027, + "unsafe_string_unmarshal": false, + "buffer_reuse_marshal": true, + "marshal_ns_op": 1569, + "unmarshal_ns_op": 2125, + "total_ns_op": 3694, "serialization_size": 133, "marshal_alloc_bytes": 1360, "unmarshal_alloc_bytes": 1800, @@ -799,13 +903,14 @@ var data = [ }, { "name": "benc", - "marshal_iter_count": 14335579, - "unmarshal_iter_count": 10264022, - "total_iter_count": 24599601, + "marshal_iter_count": 13989396, + "unmarshal_iter_count": 10480720, + "total_iter_count": 24470116, "unsafe_string_unmarshal": false, + "buffer_reuse_marshal": false, "marshal_ns_op": 82, - "unmarshal_ns_op": 115, - "total_ns_op": 197, + "unmarshal_ns_op": 118, + "total_ns_op": 200, "serialization_size": 51, "marshal_alloc_bytes": 64, "unmarshal_alloc_bytes": 32, @@ -820,13 +925,14 @@ var data = [ }, { "name": "benc/usafe", - "marshal_iter_count": 13128310, - "unmarshal_iter_count": 31974120, - "total_iter_count": 45102430, + "marshal_iter_count": 13662640, + "unmarshal_iter_count": 29888290, + "total_iter_count": 43550930, "unsafe_string_unmarshal": true, - "marshal_ns_op": 86, - "unmarshal_ns_op": 40, - "total_ns_op": 126, + "buffer_reuse_marshal": false, + "marshal_ns_op": 85, + "unmarshal_ns_op": 39, + "total_ns_op": 124, "serialization_size": 51, "marshal_alloc_bytes": 64, "unmarshal_alloc_bytes": 0, @@ -841,13 +947,14 @@ var data = [ }, { "name": "mus", - "marshal_iter_count": 12037308, - "unmarshal_iter_count": 7975964, - "total_iter_count": 20013272, + "marshal_iter_count": 12473493, + "unmarshal_iter_count": 7904714, + "total_iter_count": 20378207, "unsafe_string_unmarshal": false, + "buffer_reuse_marshal": false, "marshal_ns_op": 95, - "unmarshal_ns_op": 148, - "total_ns_op": 243, + "unmarshal_ns_op": 150, + "total_ns_op": 245, "serialization_size": 46, "marshal_alloc_bytes": 48, "unmarshal_alloc_bytes": 32, @@ -861,21 +968,22 @@ var data = [ "notes": "" }, { - "name": "mus/unsafe", - "marshal_iter_count": 12755682, - "unmarshal_iter_count": 23950941, - "total_iter_count": 36706623, - "unsafe_string_unmarshal": false, - "marshal_ns_op": 93, - "unmarshal_ns_op": 52, - "total_ns_op": 145, + "name": "mus/unsafe_reuse", + "marshal_iter_count": 27326136, + "unmarshal_iter_count": 18623845, + "total_iter_count": 45949981, + "unsafe_string_unmarshal": true, + "buffer_reuse_marshal": true, + "marshal_ns_op": 47, + "unmarshal_ns_op": 65, + "total_ns_op": 112, "serialization_size": 49, - "marshal_alloc_bytes": 64, + "marshal_alloc_bytes": 0, "unmarshal_alloc_bytes": 0, - "total_alloc_bytes": 64, - "marshal_allocs": 1, + "total_alloc_bytes": 0, + "marshal_allocs": 0, "unmarshal_allocs": 0, - "total_allocs": 1, + "total_allocs": 0, "time_support": "no", "api_kind": "manual", "url": "github.com/mus-format/mus-go", @@ -883,13 +991,36 @@ var data = [ }, { "name": "baseline", - "marshal_iter_count": 30776964, - "unmarshal_iter_count": 34022644, - "total_iter_count": 64799608, + "marshal_iter_count": 15214839, + "unmarshal_iter_count": 11854268, + "total_iter_count": 27069107, + "unsafe_string_unmarshal": false, + "buffer_reuse_marshal": false, + "marshal_ns_op": 77, + "unmarshal_ns_op": 102, + "total_ns_op": 179, + "serialization_size": 47, + "marshal_alloc_bytes": 48, + "unmarshal_alloc_bytes": 32, + "total_alloc_bytes": 80, + "marshal_allocs": 1, + "unmarshal_allocs": 2, + "total_allocs": 3, + "time_support": "no", + "api_kind": "manual", + "url": "", + "notes": "This is a manually written encoding, designed to be the fastest possible for this benchmark." + }, + { + "name": "baseline/unsafe_reuse", + "marshal_iter_count": 30344418, + "unmarshal_iter_count": 37627855, + "total_iter_count": 67972273, "unsafe_string_unmarshal": true, + "buffer_reuse_marshal": true, "marshal_ns_op": 39, - "unmarshal_ns_op": 30, - "total_ns_op": 69, + "unmarshal_ns_op": 29, + "total_ns_op": 68, "serialization_size": 47, "marshal_alloc_bytes": 0, "unmarshal_alloc_bytes": 0, @@ -904,13 +1035,14 @@ var data = [ }, { "name": "fastape", - "marshal_iter_count": 9787380, - "unmarshal_iter_count": 24863469, - "total_iter_count": 34650849, + "marshal_iter_count": 9971036, + "unmarshal_iter_count": 25212075, + "total_iter_count": 35183111, "unsafe_string_unmarshal": true, - "marshal_ns_op": 119, + "buffer_reuse_marshal": false, + "marshal_ns_op": 118, "unmarshal_ns_op": 49, - "total_ns_op": 168, + "total_ns_op": 167, "serialization_size": 55, "marshal_alloc_bytes": 64, "unmarshal_alloc_bytes": 0, diff --git a/report/index.html b/report/index.html index 0768238..2188a7a 100644 --- a/report/index.html +++ b/report/index.html @@ -110,6 +110,7 @@

Metrics

  • allocs/Op: The number of heap allocations per operation.
  • Serialization Size: The amount of bytes used to encode a marshalled value.
  • Unsafe Str Unmarshal: Whether unmarshalled strings are safe to use or if their value is modified if the underlying backing byte array is modified.
  • +
  • Buffer Reuse Marshal: Whether marshalling reuses its internal buffer for every operation.
  • Time Support: How the serializer supports time.Time values. Options: