Alignment and padding
- Rust course
- Expert
- Lesson 9/46
- 4 min
Learn alignment and padding.
Alignment and padding
Every type has an alignment: a value can only sit at addresses that are multiples of that number. For primitives, alignment is usually equal to size (u8: 1, u16: 2, u32: 4, u64: 8). A compound type's alignment is the largest alignment among its fields; the empty bytes in between are called padding:
align_of::<u64>() // 8
size_of::<(u8, u32)>() // 8: 1 + 3 padding + 4
size_of::<[u16; 3]>() // 6: no padding between array elementsUnaligned access is slow on some processors and a hardware fault on others; that's why Rust guarantees alignment through the type system.
Cache and size
Small data fits into more cache lines and is processed faster. In a vector with millions of elements, 8 bytes of padding per struct means megabytes of wasted memory. Common improvements: reordering fields, packing bool flags into bit fields, using a u32 index instead of usize where enough, switching to a "struct of arrays" layout.
// array of structs // struct of arrays
struct P { x: f32, y: f32 } struct Ps { x: Vec<f32>, y: Vec<f32> }
Vec<P> // a loop touching only x is fasterPractice Alignment and size
Print align_of::<u64>(), size_of::<(u8, u32)>() and size_of::<[u16; 3]>() on one line separated by spaces.
Starter code
use std::mem::{align_of, size_of};
fn main() {
// buraya yaz
}Sample solution
use std::mem::{align_of, size_of};
fn main() {
println!("{} {} {}", align_of::<u64>(), size_of::<(u8, u32)>(), size_of::<[u16; 3]>());
}Expected output
8 8 6
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What can be done in repr(C) to shrink a struct's size?
- Use a Box
- Order the fields by alignment from largest to smallest by hand Correct answer
- Nothing
- Make the fields private
Explanation: repr(C) keeps the order; the programmer must reorder. repr(Rust) does it automatically.
2 Ask for the alignment
println!("{}", std::mem::____::<u64>()); // 8
println!("{}", std::mem::align_of::<u64>()); // 8
Explanation: align_of gives the type's alignment.
3 Type and size
| Term | Meaning |
|---|---|
(u8, u32) |
8 |
[u16; 3] |
6 |
(u8, u8) |
2 |
(u64, u8) |
16 |