Hi Vitali,
Good news: The two schemas you wrote have identical wire size. I'd recommend going with the cleaner struct list rather than parallel lists.
Details:
- Struct lists are "flattened", meaning the structs are stored consecutively with nothing in between.
- Fields of a struct are not "tagged" like with protobuf; instead, fields are identified by their fixed offsets. A struct containing two float32's is exactly 8 bytes -- 4 byte for each field.
- A struct list is prefixed by a single 8-byte tag describing the size of each element, whereas primitive lists (e.g. List(Float32)) requires no tag. But, your parallel-arrays schema has two 8-byte pointers in Aggregate whereas the struct-list version has 1. So these cancel out, and the size ends up identical.
However, note that if you had a Vector3f containing three Float32's, each element would be padded up to an 8-byte boundary for alignment reasons. In that case, parallel arrays would be 25% smaller than the struct list because they avoid the padding. I would still recommend using a struct list, though, and using some sort of compression to remove the padding if it's important.
-Kenton