      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
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119

    extern crate regex;
    extern crate separator;
    extern crate time;

    use std;
    use std::fs::File;
    use std::io::prelude::*;
    use std::io::{Error, ErrorKind};

    use self::regex::Regex;
    use self::separator::Separatable;
    use self::time::precise_time_ns;

    #[derive(Debug)]
    pub struct Measure {
        pub min: u64,
        pub max: u64,
        time: u64,
        last: u64,
        data: Vec<u64>,
        pub name: String,
    }

    impl Measure {
        /// Constructs a new `Measure`.
        ///
        /// # Parameter
        /// - `name` Name of measured component.
        pub fn new(name: String) -> Self {
            Measure {
                min: u64::max_value(),
                max: 0u64,
                time: 0u64,
                last: 0u64,
                data: Vec::with_capacity(1_000_000),
                name: name,
            }
        }

        /// Start measurement
        pub fn start(&mut self) {
            self.last = precise_time_ns();
        }

        /// Pause measurement
        pub fn pause(&mut self) {
            if self.last == 0 {
                #[cfg(debug_assertions)]
                println!("WARNING: {:?} pause called without start!", self);

                return;
            }

            self.time += self.time_diff();
        }

        /// Stop measurement and calculate time difference
        pub fn stop(&mut self) {
            if self.last == 0 {
                #[cfg(debug_assertions)]
                println!("WARNING: {:?} stop called without start!", self);

                return;
            }

            self.time += self.time_diff();
            self.data.push(self.time);

            if self.time < self.min {
                self.min = self.time;
            }

            if self.time > self.max {
                self.max = self.time;
            }

            self.time = 0u64;
            self.last = 0u64;
        }

        fn time_diff(&mut self) -> u64 {
            let current_time = precise_time_ns();
            let time_diff = current_time - self.last;
            self.last = current_time;

            time_diff
        }

        fn write_data(&self) -> std::io::Result<()> {
            let re = Regex::new(r"[^\w\-.]")
                .or(Err(Error::new(ErrorKind::Other, "Create filename regex failed.")))?;

            let file_name = format!("measure_{}.txt", self.name);
            let file_name = re.replace_all(file_name.as_str(), "_").to_string();
            println!("{}: Write data to {}", self.name, file_name);

            let mut file = File::create(file_name)?;

            for value in &self.data {
                file.write_fmt(format_args!("{}\n", value))?;
            }

            Ok(())
        }
    }

    impl Drop for Measure {
        /// Print measure results and write times to file
        fn drop(&mut self) {
            println!("{}:\n\tmin: {} ns\n\tmax: {} ns",
                     self.name,
                     self.min.separated_string(),
                     self.max.separated_string());

            if let Err(e) = self.write_data() {
                println!("{}: Write measure data failed: {}", self.name, e);
            }
        }
    }

# Help

## Keyboard Shortcuts

?
  Show this help dialog
S
  Focus the search field
⇤
  Move up in search results
⇥
  Move down in search results
⏎
  Go to active search result
+
  Collapse/expand all sections

## Search Tricks

Prefix searches with a type followed by a colon (e.g. `fn:`) to restrict the search to a given type.

Accepted types are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`.

Search functions by type signature (e.g. `vec -> usize` or `* -> vec`)