proto3 encoding - struct vs marshaled struct

88 views Asked by At

I wish to know if there could be any significant difference in terms of mem efficiency between marshaling a struct and marshaling a marshaled struct.

Example: Assume we have a struct B with some fields.

message B{...}

The common representation:

message A {
    B b = 1;
}

Another way:

message A {
    bytes b = 1;
}

Where b is a marshaled B struct.

Generally, is it a good practice? any efficiency implications?

Thanks, Elad

2

There are 2 answers

0
Marc Gravell On

At the payload level, they are identical - however, in terms of how implementations treat them, there may be differences. The most obvious difference is that you can't use a bytes until you further deserialize it; this has pros and cons:

  • if you weren't ever going to touch it anyway, this could be fine and advantageous - avoiding some CPU processing that you didn't need for read or write; this will also mean that any downstream allocations (strings, etc) don't need to happen - so you only have a single allocation chunk: easy and efficient
  • if you do need to read it, then in addition to making life less convenient, you could have allocated an extra chunk of memory for the raw form (a chunk of bytes), and you'll need to allocate for the deserialized form; if you went straight to the deserialized form, most implementations would have skipped that intermediate allocation

So: yes, it will have different characteristics. Whether they are advantageous (or the opposite) depends on whether you also need to do the extra deserialization step on the bytes payload

0
YaFred On

I think it's a bad practice to declare a bytes field instead of a struct you would have otherwise specified in a proto file.

It's called a specification hole: you will have to write an additional documentation to describe how the receiver has to understand the bytes