Skip to content

Instantly share code, notes, and snippets.

@up1
Last active September 23, 2026 15:58
Show Gist options
  • Select an option

  • Save up1/9a9e8765dacbfa830f1cf052b8306343 to your computer and use it in GitHub Desktop.

Select an option

Save up1/9a9e8765dacbfa830f1cf052b8306343 to your computer and use it in GitHub Desktop.
Rust :: vec vs box
use std::mem::size_of;
#[derive(Debug, Clone)]
pub struct NaiveRecord {
pub rtype: u16,
pub ttl: u32,
pub rdata: Vec<u8>, // Heap allocation per record + 24-byte Vec metadata (ptr, cap, len)
}
#[derive(Debug, Clone)]
pub struct NaiveCacheEntry {
pub qname: String, // Heap allocation for qname + 24-byte String struct
pub hits: u32,
pub answers: Vec<NaiveRecord>, // Heap allocation for answers list + 24-byte Vec metadata
pub authority: Vec<NaiveRecord>, // 24 bytes empty
pub additional: Vec<NaiveRecord>, // 24 bytes empty
}
#[derive(Debug, Clone)]
pub struct OptimizedRecord {
pub rtype: u16,
pub ttl: u32,
pub rdata: Box<[u8]>, // 16 bytes overhead (ptr + len), no capacity
}
#[derive(Debug, Clone)]
pub struct OptimizedCacheEntry {
pub qname: Box<str>, // 16 bytes overhead instead of 24 bytes String
pub hits: u32,
pub answers: Box<[OptimizedRecord]>, // 16 bytes overhead instead of 24 bytes Vec
pub authority: Box<[OptimizedRecord]>, // 16 bytes overhead
pub additional: Box<[OptimizedRecord]>,// 16 bytes overhead
}
--- STACK SIZE COMPARISON ---
NaiveCacheEntry stack size: 104 bytes
OptimizedCacheEntry stack size: 72 bytes
--- MEMORY CONSUMPTION PER CACHE ENTRY ---
Naive Entry Total: 282 bytes (Stack + Heap)
Optimized Entry Total: 138 bytes (Stack + Heap)
Memory Savings: 144 bytes (51.06% reduction per entry)
--- SCALED TO 1 MILLION ENTRIES ---
Naive Total: 268.94 MB
Optimized Total: 131.61 MB
Memory Savings: 137.33 MB
fn main() {
// Create a typical DNS response (e.g. 1 IPv4 address record)
let domain = "cloudflare.com";
let ip_bytes = [104, 16, 132, 229]; // 4-byte A record
// Create Naive Entry (Vecs typically overallocate capacity)
let mut naive_answers = Vec::with_capacity(4); // Typical Vec re-alloc strategy
naive_answers.push(NaiveRecord {
rtype: 1, // A
ttl: 300,
rdata: ip_bytes.to_vec(),
});
let naive_entry = NaiveCacheEntry {
qname: domain.to_string(),
hits: 1,
answers: naive_answers,
authority: Vec::new(),
additional: Vec::new(),
};
// Create Optimized Entry (Boxed slices fit exact size)
let opt_entry = OptimizedCacheEntry {
qname: domain.to_string().into_boxed_str(),
hits: 1,
answers: vec![OptimizedRecord {
rtype: 1,
ttl: 300,
rdata: ip_bytes.to_vec().into_boxed_slice(),
}]
.into_boxed_slice(),
authority: vec![].into_boxed_slice(),
additional: vec![].into_boxed_slice(),
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment