Search code examples
c#flatbuffers

C#: FlatBuffers results are too big


According to FlatBuffers documentation, Default values don't take space on the wire. I wanted to test this so here's my code:

I'm using this schema:

table FlatCard
{
    cardIndex:ushort;
    level:byte = 1;
    damage:ushort;
    health:ushort;
}

root_type FlatCard;

And here's the C# code:

var builder = new FlatBufferBuilder(1);
FlatCard.StartFlatCard(builder);
FlatCard.AddDamage(builder, 10);
Offset<FlatCard> offset = FlatCard.EndFlatCard(builder);
FlatCard.FinishFlatCardBuffer(builder, offset);
byte[] bytes = builder.SizedByteArray();
Console.WriteLine(bytes.Length);

The actual result is 24, but I expect it to be 7 at most (3 ushort and 1 byte). Which part I'm doing/understanding wrong?


Solution

  • Almost no serialization format saves just the raw bits of the data types to disk. If it did that, there would be no way to have forwards/backwards compatibility when extending the schema, or to know which fields are present, etc.

    FlatBuffers in particular achieves this features using offsets and vtables, which cost space. It also uses alignment so the data can efficiently be read into memory. The space overhead shrinks though as your data gets bigger.

    In your case you have 8 bytes of raw data (the byte has to be aligned to the shorts), a vtable offset for the root table (4 bytes), a vtable (4 fields + 2 fixed, 16bits each, total of 12 bytes) and a root table offset (4 bytes). That would be 28 bytes, but it is 24 because you're not using all fields. A fair bit gets lost here in alignment between 32-bit and 16-bit items too.

    For more information on the format, read: https://google.github.io/flatbuffers/flatbuffers_internals.html