There are many community benchmarks that include protobuf and/or grpc, but whether they are representative of your use case is a different question. Most comparisons I've seen are either basic, use suboptimal message definitions, or have been specifically designed to make Protobuf look bad (e.g. benchmarks from competitors that are trying to establish themselves). IMO it's best to create your own benchmarks if you need reliable results for your specific use case.
Here are a few guidelines for message definitions that should generally help performance:
- prefer field ids below 16 (5 bit)
- avoid deep message nesting
- use varint types (uint32, sint32) for small numbers (ideally max 7 bit, i.e., 0-128)
- use fixed-width types (fixed32, sfixed32, etc.) for large numbers
- use with caution: groups can be serialized more efficiently than messages, but they have been deprecated and the syntax is terrible
The performance impact also depends a lot on the actual implementation, e.g., deep nesting hits harder on implementations that don't cache the computed size.