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 {
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,
}
}
pub fn start(&mut self) {
self.last = precise_time_ns();
}
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();
}
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 {
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);
}
}
}