Use std::time::Instant to measure the duration of a code block by calling Instant::now() at the start and .elapsed() at the end, which returns a Duration object. This type is monotonic, meaning it is immune to system clock adjustments, making it the correct choice for performance profiling rather than wall-clock time tracking.
Here is a practical example measuring the execution time of a computation:
use std::time::Instant;
fn main() {
let start = Instant::now();
// Simulate some work
let mut sum = 0;
for i in 0..1_000_000 {
sum += i;
}
let duration = start.elapsed();
println!("Computation took: {:?}", duration);
println!("Milliseconds: {} ms", duration.as_millis());
}
For more granular control or when you need to measure multiple distinct sections within a function, you can capture the instant and calculate the difference manually using Duration::sub. This is useful when you need to log intermediate checkpoints without blocking the flow:
use std::time::{Instant, Duration};
fn process_data(data: &[i32]) {
let start = Instant::now();
// Phase 1: Validation
for &item in data {
if item < 0 { panic!("Negative value"); }
}
let validation_time = start.elapsed();
// Phase 2: Transformation
let transformed: Vec<i32> = data.iter().map(|&x| x * 2).collect();
let total_time = start.elapsed();
println!("Validation: {:?}", validation_time);
println!("Total processing: {:?}", total_time);
println!("Transformation took: {:?}", total_time - validation_time);
}
Remember that Instant does not provide access to the actual system time (like "14:30:00"); it only tracks the delta since the program started or since the Instant was created. If you need to log the actual timestamp alongside the duration, combine Instant with std::time::SystemTime. Also, be aware that elapsed() is a blocking call that queries the underlying system clock, so avoid calling it in tight loops where nanosecond precision is required; instead, cache the Instant and compute differences only when necessary.