Rust Measuring Time
std::time is the standard library module for time. Duration is a length of time.
A length of time
A Duration is just a length. Build one from seconds, milliseconds and more:
let wait = Duration::from_millis(1500);
println!("whole seconds = {}", wait.as_secs());
println!("total millis = {}", wait.as_millis());
println!("debug = {:?}", wait);Add lengths together
let lesson = Duration::from_secs(45 * 60);
let break_time = Duration::from_secs(10 * 60);
let total = lesson + break_time;
println!("total minutes = {}", total.as_secs() / 60);
println!("checked add works = {}", lesson.checked_add(break_time).is_some());Time something with Instant
Start the stopwatch, do the work, then ask how much time passed:
let start = Instant::now();
std::thread::sleep(Duration::from_millis(30));
let elapsed = start.elapsed();
println!("slept at least 30 ms = {}", elapsed >= Duration::from_millis(30));Set a deadline
Add a Duration to an Instant to get a deadline. duration_since gives 0ns once the moment has passed — it never goes negative:
let deadline = Instant::now() + Duration::from_millis(40);
std::thread::sleep(Duration::from_millis(90));
println!("time left = {:?}", deadline.duration_since(Instant::now()));
println!("deadline passed = {}", Instant::now() >= deadline);The wall clock and the epoch
SystemTime counts from the UNIX epoch: midnight at the start of 1 January 1970, UTC. Adding a Duration gives any fixed moment:
let moment = UNIX_EPOCH + Duration::from_secs(1_700_000_000);
let seconds = moment.duration_since(UNIX_EPOCH).unwrap();
println!("seconds since epoch = {}", seconds.as_secs());Example
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
fn main() {
// Split 3,661 seconds into hours, minutes and seconds.
let session = Duration::from_secs(3661);
let hours = session.as_secs() / 3600;
let minutes = (session.as_secs() % 3600) / 60;
let seconds = session.as_secs() % 60;
println!("session = {}h {}m {}s", hours, minutes, seconds);
// Add a warm-up.
let warm_up = Duration::from_secs(600);
let total = warm_up + session;
println!("with warm-up = {} seconds", total.as_secs());
// Time a short rest with the stopwatch.
let start = Instant::now();
std::thread::sleep(Duration::from_millis(25));
println!("rested at least 25 ms = {}", start.elapsed() >= Duration::from_millis(25));
// A fixed wall-clock moment as plain epoch seconds.
let moment: SystemTime = UNIX_EPOCH + Duration::from_secs(1_700_000_000);
println!("moment = {} seconds after the epoch", moment.duration_since(UNIX_EPOCH).unwrap().as_secs());
}Key points
- std::time has three tools.
- Duration is a length of time.
- Instant is a stopwatch for measuring.
- SystemTime is a wall-clock moment.
- Duration prints itself in a short form: 1500 milliseconds shows as 1.5s with {:?}
- Instant only moves forward.
- It never jumps when the computer's clock is changed.
- That makes it the safe choice for timing code.
- SystemTime can move backwards if the clock is adjusted.
- Use it for timestamps and dates.
- Never use it for measuring how long code took.
- std::time::Duration has no sign.
- Use chrono `TimeDelta` when a gap can run backwards, such as a date difference.
- point.duration_since(earlier) gives you the Duration.
In this example, we do three jobs with std::time. First, a Duration of 3,661 seconds is split with division and remainder into 1 hour, 1 minute and 1 second. Second, adding a 600-second warm-up with + gives 4,261 seconds in total. Third, an Instant stopwatch checks that a 25-millisecond sleep really took at least that long. At the end, a SystemTime is built by adding seconds to UNIX_EPOCH, and duration_since reads the same seconds back. Every number here is fixed, so the output never changes.
Note
Instant and SystemTime are points in time.
Duration is the gap between two points.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Rust Playground
Exercise
You want to measure how long a function takes to run. Which tool do you reach for?