Rust Performance Basics Measure First Then Change One Thing
The handful of habits behind most Rust speed: build in release, avoid needless allocation, use iterators and slices, pick the right collection and measure before tuning.

There are about six things that account for most of the difference between slow and fast Rust, and none of them involve assembly. They are habits you can apply while writing, then confirm with a profile. This post lists them with the reason and a code example for each. It is the first stop after the profiling guide.
Rust 1.90, edition 2024.
1. Build with --release
cargo build --releaseDebug builds disable inlining, keep overflow checks and skip most optimizations. The gap depends on the code, but a loop-heavy program can be many times slower in debug. Details in release versus debug.
2. Borrow, do not copy
fn count_words(text: &str) -> usize {
text.split_whitespace().count()
}Taking &str means callers pass a String, a literal or a slice of a file buffer without any copy. A signature with String parameters forces clones at call sites; see String versus str.
3. Avoid allocating in loops
let mut line = String::new();
for _ in 0..1000 {
line.clear();
read_into(&mut line);
process(&line);
}clear() keeps the capacity, so the buffer is reused. Creating a new String per iteration allocates and frees a thousand times. See reusing buffers.
4. Pre-size collections
let mut out = Vec::with_capacity(items.len());Without it a Vec grows by doubling, which copies on every doubling. If you know the final size, say so.
5. Buffer I/O
use std::io::{BufWriter, Write};
let mut out = BufWriter::new(std::io::stdout().lock());
for i in 0..100_000 {
writeln!(out, "{i}").unwrap();
}Unbuffered writes cost a system call each. File and socket reads work the same way.
6. Choose the right data structure
A Vec lookup with contains inside a loop is quadratic. A HashSet makes it linear. Sorted Vec plus binary search beats a BTreeMap for read-mostly data. These choices dwarf the other items when the data is large.
What this list does not do
It does not make the code fast in the places that matter; a profile does. Measure first, as described in profiling Rust programs, then apply the habit that matches the hot spot. Clever tricks such as unsafe indexing or manual SIMD belong at the end, after algorithmic and allocation work. The official guidance is in the Rust Performance Book, under general tips.


