1: No, it is not usually fixed. By default, int
and long
(and a few others) are encoded with "varint" encoding (either straight or zig-zag), which is designed to optimize for small magnitude - it is a 7-bit encoding with the 8-th bit used as a continuation flag. However, there are options that allow you to use fixed size (4-byte or 8-byte) encodings for the same data - the DataFormat
switch on the ProtoMemberAttribute
controls this. double
always takes 8 bytes. Additionally, it is possible that some fields may be optional (nullable, with default values, or with conditional serialization), in which case the number of fields in the message is variable.
2: Strings are binary encoded using UTF-8, then the number of bytes is written as a "varint", followed by the payload bytes - so the length of the string, and the particular characters used (since UTF-8 itself uses different numbers of bytes per-character, depending on the character), greatly affect the resulting length.