Skip to content

Commit

Permalink
feat: speed up ProtoMethods
Browse files Browse the repository at this point in the history
The ProtoMethods is called for every unmarshal, which in turn allocates
an protoiface.Methods. The Methods object does not refer to a partucular
message object, so the allocation can be saved by one-time initialization
at startup.

Found by the the alecthomas/go_serialization_benchmarks suite:

    go test -bench='Pulsar' -memprofile mem.out  -cpu 6  ./

Before:
goos: darwin
goarch: arm64
pkg: github.com/alecthomas/go_serialization_benchmarks
Benchmark_Pulsar_Marshal-6     	 7480744	       154.1 ns/op	        51.57 B/serial	      96 B/op	       2 allocs/op
Benchmark_Pulsar_Unmarshal-6   	 5057922	       236.9 ns/op	        51.60 B/serial	     256 B/op	       7 allocs/op

After:
Benchmark_Pulsar_Marshal-6     	 7251019	       153.9 ns/op	        51.57 B/serial	      96 B/op	       2 allocs/op
Benchmark_Pulsar_Unmarshal-6   	 6409070	       187.2 ns/op	        51.63 B/serial	     160 B/op	       5 allocs/op
  • Loading branch information
elias-orijtech committed Mar 20, 2023
1 parent 760914f commit 743ad54
Showing 1 changed file with 9 additions and 2 deletions.
11 changes: 9 additions & 2 deletions features/fastreflection/proto_message.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,19 +288,26 @@ func (g *fastGenerator) genIsValid() {
}

func (g *fastGenerator) genProtoMethods() {
varName := g.typeName + "ProtoMethods"

g.P("// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations.")
g.P("// This method may return nil.")
g.P("//")
g.P("// The returned methods type is identical to")
g.P(`// "google.golang.org/protobuf/runtime/protoiface".Methods.`)
g.P("// Consult the protoiface package documentation for details.")
g.P("func (x *", g.typeName, ") ProtoMethods() *", protoifacePkg.Ident("Methods"), " {")
g.P("func (*", g.typeName, ") ProtoMethods() *", protoifacePkg.Ident("Methods"), " {")
g.P("return ", varName)
g.P("}")

g.P("var ", varName, " *", protoifacePkg.Ident("Methods"))

g.P("func init() {")
g.genSizeMethod()
g.genMarshalMethod()
g.genUnmarshalMethod()

g.P("return &", protoifacePkg.Ident("Methods"), "{ ")
g.P(varName, " = &", protoifacePkg.Ident("Methods"), "{ ")
g.P("NoUnkeyedLiterals: struct{}{},")
g.P("Flags: ", protoifacePkg.Ident("SupportMarshalDeterministic"), "|", protoifacePkg.Ident("SupportUnmarshalDiscardUnknown"), ",")
g.P("Size: size,")
Expand Down

0 comments on commit 743ad54

Please sign in to comment.