macrotime/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//! # TimeIt
//! `TimeIt` is very easy to use. To time the execution of a block of code:
//! ```
//! use timeit::*;
//! let time = time!({
//!     // do some stuff...
//! });
//! println!("This operation took {} ms!", time.as_millis());
//! ```
//! You can also have `TimeIt` print the time taken to perform a task on its own. To do this:
//! ```
//! use timeit::*;
//! dbg_time!({
//!     // do some stuff...
//! });
//! ```
//! In this scenario, the time will printed in the most relevant unit, so no need for formatting.

pub use std::time::{Duration, Instant};

/// Prints the execution time of the provided expression.
#[macro_export]
macro_rules! dbg_time {
    ($x:expr) => {
        // time expression
        let elapsed = $crate::time!($x);

        // log elapsed time
        if elapsed < $crate::Duration::from_millis(1) {
            println!("{} us", elapsed.as_nanos());
        } else if elapsed < $crate::Duration::from_secs(1) {
            println!("{} ms", elapsed.as_millis());
        } else {
            println!("{} s", elapsed.as_secs());
        }
    };
}

/// Returns a `Duration` of the execution time of the provided expression.
#[macro_export]
macro_rules! time {
    ($x:expr) => {{
        let now = $crate::Instant::now();
        $x();
        now.elapsed()
    }};
}

#[cfg(test)]
mod tests {
    use super::*;

    /// Asserts that two operations of different complexities result in rational computation times.
    #[test]
    fn time() {
        let a = time!({
            let mut sum: i32 = 0;
            for i in 0..1_000 {
                sum = sum.wrapping_add(i);
            }
        });
        let b = time!({
            let mut sum: i32 = 0;
            for a in 0..1_000 {
                for b in 0..1_000 {
                    sum = sum.wrapping_add(a * b);
                }
            }
        });
        assert!(a < b);
    }
}