In this lesson, you will learn how to arrange your struct fields to reduce memory footprint by minimizing alignment padding.
The Problem: Invisible Padding
When you define a struct in Rust, the compiler must ensure that each field starts at a memory address that is a multiple of its size. For example, a 4-byte integer usually needs to start at an address divisible by 4. If you place a 1-byte bool before a 4-byte u32, the compiler adds 3 "padding" bytes of wasted space to satisfy this requirement.
Consider this inefficient struct:
struct Inefficient {
a: u8, // 1 byte
b: u32, // 4 bytes (needs to start on a 4-byte boundary)
c: u8, // 1 byte
}
In the example above, Rust cannot place b immediately after a. It inserts 3 bytes of padding after a so that b starts at an address divisible by 4. Then, it adds 3 more bytes of padding after c to ensure the total size of the struct is a multiple of its largest member. This struct occupies 12 bytes total, even though the data only accounts for 6 bytes!
The Solution: Sorting by Size
To minimize memory consumption, you should group your fields by their size, generally ordering them from largest to smallest. By placing larger types first, you ensure that smaller types fill the gaps that would otherwise be wasted as padding.
If we rearrange Inefficient into an Efficient structure:
struct Efficient {
b: u32, // 4 bytes
a: u8, // 1 byte
c: u8, // 1 byte
// 2 bytes of implicit padding here
}
By reordering, the total size drops from 12 bytes down to 8 bytes. You have effectively reclaimed 4 bytes of wasted memory without changing the actual data you are storing. While the compiler handles alignment automatically to keep your program safe, you have control over how efficiently your data structures inhabit the heap or stack. Always look at your field types and consider if the order allows the compiler to pack them tightly together.
Key Takeaway: Order your struct fields from largest to smallest to minimize padding and reduce the total memory footprint of your data structures.