Rust Optimization Tips
Assess when and where there are performance optimizations [fn:1].
General Optimizations
Section titled “General Optimizations”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`
Example optimized
Section titled “Example optimized”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);}