Skip to content

Rust Optimization Tips

Assess when and where there are performance optimizations [fn:1].

Borrow instead of clone, avoid Unnecessary Memory Allocations

Section titled “Borrow instead of clone, avoid Unnecessary Memory Allocations”

Example: pass using references if value is not needed yet

Ask the map once with entry, Avoid repeating work

Section titled “Ask the map once with entry, Avoid repeating work”

Example: if possible, combine multiple look ups on variable

Parallelism counting with Rayon, Use all cores on your machine

Section titled “Parallelism counting with Rayon, Use all cores on your machine”

Example: use rayon crate to convert sequential computation into parallel computation with one call - `pariter` instead of `iter`

Parses a log and extracts user names in first column of comma separated line and shows top ten users.

fn top_users(log &str) -> Vec<(String, u64)> {
let counts: HashMap<&str, u64> = log
// Parallel run with rayon
.par_lines()
.fold(HashMap::new, |mut ace, line| {
let user = line.split(',').nth(1).unwrap();
// instead of looking up user multiple times, use entry()
*acc.entry(user).or_insert(0) += 1;
acc
})
.reduce(HashMap::new, |mut a, b| {
for (k, v): in b { *a.entry(k).or_insert(0) += v }
a
})
let mut ranked: Vec<(&str, u64)> = counts.into_iter().collect();
ranked.sort_by(|a, b| b.1.cmp(&a.1));
ranked.truncate(10);
ranked.into_iter()
// Use borrowed value and call to_string() when value is needed
.map(|(user, n)| (user.to_string(), n))
.collect()
}

swapremove when order does not matter - Avoid expensive operations with vector

Section titled “swapremove when order does not matter - Avoid expensive operations with vector”

Example: use swap_remove instead of remove for a remove item from a vector if order does not matter. Results in a ~7,000x faster execution.

fn end_session(sessions: &mut Vec<Session>, idx: usize) {
// swap_remove() instead of remove()
sessions.swap_remove(idx);
}