What happens when smart pointers are used in enums

Migo·2024년 8월 20일
0

Fluent Rust

목록 보기
25/27
post-thumbnail

Enum

In Rust, except for unit like enum or c-like enum with values lower than 255 where every variants are internally considered single byte value, when you have enum the following:

enum {
	Empty,
    Integer(i32),
    Vector(Vec<i32>)
}

It's actually represented with enum tag that accounts for single byte. So, when you think about padding and how computer data on memory are scanned through, the actually size of enum above is 32bytes - yes, 32 bytes, NOT 24 bytes or the like.

Why is it? It is because the size of enum required follows that of largest variant in enum.

Here, smartpointer vector takes 24bytes (for cap, ptr, len) and single enum tag makes the total size 25bytes AND with the padding, it becomes 32bytes.

Wait, isn't too wasteful?

Yes, if you think about the nature of vector which actually stores the most important data on the heap, you can actually wrap it with Box data type which takes just 8bytes(on 64bit architecture), making it 16bytes in total.

enum {
	Empty,
    Integer(i32), // 4bytes
    Vector(Box<Vec<i32>>) // 16bytes
}

So the size of enum above becomes 16 bytes, half the size as before.

Still, Box should take just 8bytes on 64-bit architecture and it becomes 16bytes this time?

Yes, Exactly for that reason, for enums that are most frequently used such as Result and Option, Rust compiler optimizes them so it can be represented with one machine word(8bytes or 4bytes). Take the following example.

    let opt: Option<Box<i32>> = None;

    // get the size of opt
    let size = std::mem::size_of_val(&opt);
    println!("size of opt: {}", size); // 8bytes, not 16bytes
}


profile
Dude with existential crisis

0개의 댓글

관련 채용 정보