Ben Chuanlong Du's Blog

It is never too late to learn.

Memory Layout of Enum in Rust

Things on this page are fragmentary and immature notes/thoughts of the author. Please read with your own judgement!

Tips & Traps

  1. The closest thing to describe Rust Enum is tagged Union. The Rust compiler adds an extra (up to) 8 bytes to the enum to store the discriminator. This is used to identify the variant currently stored in the enum. However, Rust does NOT guarantee that the memory layout of an enum is always a tag followed by a union. Instead, the Rust compiler retains the freedom to optimize the layout of types so that the code can be more memory efficient.

  2. The size of an enum type depends on its largest variant. Generally speaking, it is the the size of the largest variant type plus 8 bytes (tag for distinguishing variants). For example, the following enum

     :::Rust
     enum MyEnum {
         A(Vec<u64>),
         B(isize),
         C(usize),
     }
    
    

    has the largest variant Vec<usize> which takes 24 bytes on stack. And since there's an extra 8 bytes for the tag, the total size of MyEnum on the stack is 32 bytes. However, the Rust compiler is able to optimize away the tag in certain situaitons. For example, the type Result<Vec<u64>, usize> takes only 24 bytes on the stack due to niche optimization. For more discussions, please refer to Size of the type Result<Vec, u64>.

In [11]:
:dep memuse = "0.2.1"
In [12]:
use memuse::DynamicUsage;
In [19]:
std::mem::size_of::<Vec<u64>>()
Out[19]:
24
In [21]:
std::mem::size_of::<&Vec<u64>>()
Out[21]:
8
In [22]:
std::mem::size_of::<&[u64]>()
Out[22]:
16
In [13]:
type T1 = Result<Vec<u64>, usize>;
std::mem::size_of::<T1>()
Out[13]:
24
In [16]:
let v1: T1 = Ok(Vec::with_capacity(10));
v1.dynamic_usage()
Out[16]:
80
In [17]:
let v2: T1 = Err(100);
v2.dynamic_usage()
Out[17]:
0
In [8]:
type T2 = Result<String, usize>;
std::mem::size_of::<T2>()
Out[8]:
24
In [24]:
enum MyEnum {
    A(Vec<u64>),
    B(isize),
    C(usize),
}

std::mem::size_of::<MyEnum>()
Out[24]:
32
In [ ]:

Comments