Time

Joule provides two types for time measurement: Duration for time spans and Instant for timestamps.

Duration

A time span measured in nanoseconds. All arithmetic is exact — no floating-point rounding.

Creating Durations

let d1 = Duration::from_secs(5);          // 5 seconds
let d2 = Duration::from_millis(1500);     // 1.5 seconds
let d3 = Duration::from_micros(250);      // 250 microseconds
let d4 = Duration::from_nanos(100);       // 100 nanoseconds

Querying

let d = Duration::from_millis(2500);
d.as_secs();      // 2
d.as_millis();    // 2500
d.as_micros();    // 2500000
d.as_nanos();     // 2500000000
d.is_zero();      // false

Arithmetic

let a = Duration::from_secs(3);
let b = Duration::from_millis(500);

let sum = a.add(&b);           // 3.5 seconds
let diff = a.sub(&b);          // 2.5 seconds
let doubled = a.mul(2);        // 6 seconds
let halved = a.div(2);         // 1.5 seconds

// Checked arithmetic (returns Option)
let safe = a.checked_add(&b);  // Option::Some(3.5s)
let over = a.checked_sub(&Duration::from_secs(10)); // Option::None

Instant

A monotonic timestamp. Cannot go backwards. Used for measuring elapsed time.

Measuring Elapsed Time

let start = Instant::now();          // 15.0 pJ — reads system clock

// ... do work ...
heavy_computation();

let elapsed: Duration = start.elapsed();
println!("Took {} ms", elapsed.as_millis());

Comparing Instants

let t1 = Instant::now();
// ... work ...
let t2 = Instant::now();

let gap: Duration = t2.duration_since(&t1);

Example: Benchmarking with Energy

#[energy_budget(max_joules = 0.001)]
fn timed_sort(data: Vec<i32>) -> (Vec<i32>, Duration) {
    let start = Instant::now();
    let sorted = sort(data);
    let elapsed = start.elapsed();
    (sorted, elapsed)
}

fn main() {
    let data = vec![5, 3, 1, 4, 2, 8, 7, 6];
    let (sorted, time) = timed_sort(data);
    println!("Sorted in {} us", time.as_micros());
}

Energy Costs

OperationCostNotes
Duration arithmetic0.05 pJInteger add/sub
Instant::now()15.0 pJSystem clock read (syscall)
elapsed()15.0 pJClock read + subtraction
duration_since()0.05 pJInteger subtraction

Instant::now() is the expensive operation — it requires a system call (clock_gettime on Linux, mach_absolute_time on macOS). Avoid calling it in tight loops. Measure coarse-grained sections instead.