Holy's Reallocation Merging
Summary
Merge together consecutive reallocations of datatypes during ser/des to prevent multiple reallocations and allow special cases to skip reallocating logic in datatypes.
Motivation
One of the biggest performance costs when it comes to serializing our messages is reallocations. Pretty much every datatype we write to a buffer has some form of reallocation. But, when we use a lot of these datatypes consecutively and we know how big they are beforehand, we can squash those allocations together and write a version of that datatype without any of the spooky logic included for reallocating. Other programs like Blink, and Squash already implement this.
Design
Holy (and by extension, light) implements reallocation merging by storing the following "extra" data about its ser/des types:
local static_ser
is an extra serialization function for types with a fixed size in bytes. The
static_ser
SerFunctions won't try to resize any buffers, they serialize their raw data with
no extra logic. Essentially, calling a static_ser
SerFunction internally means whoever is
calling the function will take care of allocations. In practice, Holy is smart enough to dynamically create closures
based on whether a generic input is static. Structs will
merge all static fields first. If all fields of a struct are static, the struct itself becomes a static type with a size
and static_ser
SerFunction. Arrays, and
Maps with Static Parameters will generate serde
special-cases to allocate the product of the data length with the static size of each
item.