3 ms·
> AFAIK the C++ implementation would always allocate on the heap for nested messages FWIW if you reuse the same message object for multiple parsings, it will r
by kentonv 6y ago
> AFAIK the C++ implementation would always allocate on the heap for nested messages
FWIW if you reuse the same message object for multiple parsings, it will re-use the sub-objects as well, thus amortizing away the allocation cost. Parsing the same message into the same object twice should do zero allocations on the second parse. This is the intended way to use Protobuf for small-size messages.
Apparently the C++ implementation has also grown support for arena allocation more recently. (After my time, so I don't know much about it.)
- tijsvd 6y agoBut then all that must come with bookkeeping, which brings its own cost. Take a look at an implementation like Prost, for Rust. It's very similar to what I did (10 years ago by now). Everything is just inline, except when messages can be recursive (which should be rare for most protocols).
- kentonv 6y agoThe bookkeeping is not that hard... the pointer is null until it is first allocated, then it remains non-null, while a separate boolean indicates whether the sub-message is actually present in the parent. The big problem is bloat in memory usage if you parse many differently-shaped messages, requiring the app to implement hacks like only reusing a particular object a certain number of times.
- haberman 6y ago> Everything is just inline, except when messages can be recursive (which should be rare for most protocols). Many messages are have lots of optional sub-message fields, and set only a few of them in any given message. These messages would be huge if everything is inline (especially if the same thing happens in those sub-messages). I agree that inlining all sub-messages works great for dense schemas, but it assumes too much about the schema to be a good design for a general-purpose proto library I think. Also maps and repeated fields can never be inline.
- tijsvd 6y agoYes, this comes back to use case. So it's great that there are different implementations for different use cases. It helps that the wire format is simple and well-documented.
- a_t48 6y agoI wish I had known this a few years ago, I could have saved some allocations. :)
- deleted 6y ago[deleted]