Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: speed up ProtoMethods #108

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

elias-orijtech
Copy link

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

CC @tac0turtle @odeke-em

@elias-orijtech elias-orijtech requested a review from a team as a code owner March 20, 2023 05:03
@elias-orijtech elias-orijtech changed the title features/fastreflection: initialize ProtoMethods once feat: speed up ProtoMethods Mar 21, 2023
@eliasnaur
Copy link

Added another optimization. Let me know if they belong in separate PRs.

@eliasnaur
Copy link

I believe the remaining allocations are intrinsic to the serialization process, and thus cannot be reduced further.

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
CheckInitialized checks for missing required fields, which is not
relevant for a proto3 implementation such as Pulsar. However, without it
protobuf will fall back to a slow fallback that allocates memory per
serialization.

Before:

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

After:

Benchmark_Pulsar_Marshal-6     	12480471	        91.47 ns/op	        51.61 B/serial	     128 B/op	       2 allocs/op
Benchmark_Pulsar_Unmarshal-6   	10919157	       108.6 ns/op	        51.58 B/serial	     128 B/op	       3 allocs/op
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants