Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Composite Layout & Endianness

On a little-endian host, can a composite be a #[repr(C)] / #[repr(C, packed)] overlay so field access is a free load?

Almost — but not via repr(C) transmute. ergo-sbe does something safer that is still a plain load on LE:

ApproachWhat ergo-sbe doesWhy not the other thing
Wire image#[repr(transparent)] pub struct Engine(pub [u8; 10]) — the value is the on-wire bytes#[repr(C)] native fields insert alignment padding; SBE is packed and may be unaligned
Accessorsfrom_le_bytes / to_le_bytes at schema offsetsNative loads break big-endian schemas and unaligned safety
FlyweightEngineDecoder { buf, pos } reads in placeDefault decode path
Eager valueengine_value() copies the N-byte image onceStill not field-by-field re-pack; .0 is the wire block
EncodeWriter copies engine.0 into the frameSame image the decoder reads back

On LE hosts, from_le_bytes lowers to a load. The generator also emits

const _: () = assert!(core::mem::size_of::<Engine>() == 10);

so the Rust type size is locked to the wire size.

*FixedFields is an application struct used to fill the fixed block in one call. It is not a zero-copy overlay; .fixed(&…) writes each field with endian conversion.

Single-field access is already one load. layout_access_bench compares flyweight, preheld [u8; N], and #[repr(C, packed)] on a mid-block field: they measure equivalently. Materialising the whole composite first is the expensive path. zerocopy FromBytes/IntoBytes was evaluated and was not faster than the flyweight mov.

You need…Use
One or a few fields on the hot pathFlyweight
Whole composite as an owned wire blobValue Engine([u8; N]) / *_value() — pay N once
Hand-rolled repr(C, packed) for speedSkip it — same cost, extra UB/layout risk

We do not generate packed field structs: packing, unaligned references, big-endian schemas, enums/sets/nested composites. The transparent wire image is the portable form that already optimizes to the packed load on LE.

On encode, encode_style_bench shows .fixed(&CarFixedFields{…}) and individual setters measure equivalently after inlining. Prefer .fixed for completeness, not speed. Building a BE image on an LE host costs a bswap per multi-byte field; once the image exists, write cost matches LE.

composite_layout_test · layout_access_bench · encode_style_bench. Read live Criterion output; do not quote numbers from this page.