In this lesson, you will learn how to minimize memory overhead by reordering struct fields to eliminate unnecessary padding bytes.
The Problem with Padding
Rust, like most C-family languages, aligns fields in memory based on their size to ensure CPU efficiency. A u64 (8 bytes) generally prefers to start at an address divisible by 8. If you place a u8 (1 byte) before a u64, the compiler inserts 7 bytes of "padding" to ensure the u64 starts on an 8-byte boundary.
Consider this inefficient structure:
struct Inefficient {
a: u8, // 1 byte
b: u64, // 8 bytes
c: u8, // 1 byte
}
In the example above, the compiler adds 7 bytes of padding after a to align b, and another 7 bytes after c to satisfy the struct's overall alignment requirement. This Inefficient struct occupies 24 bytes despite only storing 10 bytes of actual data.
Solving with Field Reordering
You can eliminate this "slack" space by sorting your fields from largest alignment to smallest. By grouping fields with similar sizes, you allow the compiler to pack them tightly without needing to insert gap bytes.
struct Efficient {
b: u64, // 8 bytes
a: u8, // 1 byte
c: u8, // 1 byte
// 6 bytes of padding here, total 16 bytes
}
By placing the u64 first, the compiler no longer needs to pad after a. While there is still a small amount of trailing padding to meet the 8-byte alignment of the u64, the total size drops from 24 bytes to 16 bytes—a 33% reduction in memory footprint.
When working with high-throughput pipelines or processing millions of items in a collection, these savings accumulate. Smaller structs mean more elements fit into a single CPU cache line, significantly improving performance by reducing cache misses during iteration. When your structures become even more complex, consider using #[repr(C)] if you need to guarantee a specific layout, but always keep your largest fields at the top of the struct definition.
Key Takeaway: Reorder your struct fields from largest alignment to smallest to pack data tightly and minimize invisible padding bytes.