Part 9 · 1 chapters · ~8 min
Performance and Profiling
Release builds and profiles (LTO, codegen-units, panic=abort), measuring with criterion, profiling with perf, cargo-flamegraph and samply, allocation profiling with dhat and heaptrack, choosing allocators (jemalloc, mimalloc), avoiding unnecessary clones and allocations, SIMD, and when Rust is not faster.
13
Measuring Rust
code
# Cargo.toml release profile for services [profile.release] lto = "thin" codegen-units = 1 debug = "line-tables-only" # keep symbols for profiling cargo flamegraph --bin ledger # perf + flame graph (Linux) / dtrace (macOS) samply record ./target/release/ledger # a profiler that opens in the Firefox Profiler UI #[global_allocator] static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; # often faster than the system allocator
Measured here: a release build of a small program was 540 KB. Rust is not automatically faster: a Rust service that clones strings in every handler, allocates per request and holds locks across awaits can be slower than well-written Go or Java. Profile first; the usual wins are fewer allocations, borrowing instead of cloning, and better algorithms.