@@ -2,19 +2,23 @@ package flatbuffers
22
33import (
44 "time"
5+ "unsafe"
56
67 "github.com/alecthomas/go_serialization_benchmarks/goserbench"
78 flatbuffers "github.com/google/flatbuffers/go"
89)
910
1011type FlatBufferSerializer struct {
11- builder * flatbuffers.Builder
12+ unsafeReuse bool
13+ builder * flatbuffers.Builder
1214}
1315
1416func (s * FlatBufferSerializer ) Marshal (o interface {}) ([]byte , error ) {
1517 a := o .(* goserbench.SmallStruct )
1618 builder := s .builder
17- builder .Bytes = nil // free
19+ if ! s .unsafeReuse {
20+ builder .Bytes = nil // free
21+ }
1822 builder .Reset ()
1923
2024 name := builder .CreateString (a .Name )
@@ -28,22 +32,38 @@ func (s *FlatBufferSerializer) Marshal(o interface{}) ([]byte, error) {
2832 FlatBufferAAddSpouse (builder , a .Spouse )
2933 FlatBufferAAddMoney (builder , a .Money )
3034 builder .Finish (FlatBufferAEnd (builder ))
31- return builder .Bytes [ builder . Head ():] , nil
35+ return builder .FinishedBytes () , nil
3236}
3337
3438func (s * FlatBufferSerializer ) Unmarshal (d []byte , i interface {}) error {
3539 a := i .(* goserbench.SmallStruct )
3640 o := FlatBufferA {}
3741 o .Init (d , flatbuffers .GetUOffsetT (d ))
38- a .Name = string (o .Name ())
42+ if s .unsafeReuse {
43+ a .Name = unsafeSliceToString (o .Name ())
44+ a .Phone = unsafeSliceToString (o .Phone ())
45+ } else {
46+ a .Name = string (o .Name ())
47+ a .Phone = string (o .Phone ())
48+ }
3949 a .BirthDay = time .Unix (0 , o .BirthDay ())
40- a .Phone = string (o .Phone ())
4150 a .Siblings = int (o .Siblings ())
4251 a .Spouse = o .Spouse ()
4352 a .Money = o .Money ()
4453 return nil
4554}
4655
4756func NewFlatBuffersSerializer () goserbench.Serializer {
48- return & FlatBufferSerializer {flatbuffers .NewBuilder (0 )}
57+ return & FlatBufferSerializer {builder : flatbuffers .NewBuilder (0 ), unsafeReuse : false }
58+ }
59+
60+ func NewFlatBuffersUnsafeReuseSerializer () goserbench.Serializer {
61+ const maxSerSize = 128
62+ return & FlatBufferSerializer {builder : flatbuffers .NewBuilder (maxSerSize ), unsafeReuse : true }
63+ }
64+
65+ // unsafeSliceToString converts a byte slice to a string in an unsafe way
66+ // (modifications to the byte slice modify the string).
67+ func unsafeSliceToString (b []byte ) string {
68+ return * (* string )(unsafe .Pointer (& b ))
4969}
0 commit comments