-
Notifications
You must be signed in to change notification settings - Fork 812
Description
gogo/protobuf/types
.Timestamp is generated by protoc-gen-gogo
and imports gogo/protobuf/proto
.
To avoid cycling import, gogo/protobuf implement a fake timestamp
.
protobuf/proto/timestamp_gogo.go
Lines 38 to 46 in 5628607
type timestamp struct { | |
Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"` | |
Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` | |
} | |
func (m *timestamp) Reset() { *m = timestamp{} } | |
func (*timestamp) ProtoMessage() {} | |
func (*timestamp) String() string { return "timestamp<string>" } | |
And it does not implement newMarshaler
or Marshaler
interface, which will cause the Marshal
use the slowest path.
protobuf/proto/table_marshal.go
Lines 2951 to 2954 in 5628607
var info InternalMessageInfo | |
siz := info.Size(pb) | |
b := make([]byte, 0, siz) | |
return info.Marshal(b, pb, false) |
Then the global marshal info lock will be performance bottleneck.
protobuf/proto/table_marshal.go
Lines 107 to 116 in 5628607
func getMarshalInfo(t reflect.Type) *marshalInfo { | |
marshalInfoLock.Lock() | |
u, ok := marshalInfoMap[t] | |
if !ok { | |
u = &marshalInfo{typ: t} | |
marshalInfoMap[t] = u | |
} | |
marshalInfoLock.Unlock() | |
return u | |
} |
A simple workaround fix is #655
A better solution is use a real Timestamp instead of a fake timestamp.
To avoid cycling import, we can import golang/protobuf and use Timestamp generated by golang protobuf.
import ptimestamp "github.com/golang/protobuf/ptypes/timestamp"
type timestamp = ptimestamp.Timestamp
Then the performance will be highly improved.