/
types.rs
207 lines (167 loc) · 4.9 KB
/
types.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
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/// This module contains common internal types.
use std::fmt;
use hyperfine::units::{Second, Unit};
#[cfg(not(windows))]
pub const DEFAULT_SHELL: &str = "sh";
#[cfg(windows)]
pub const DEFAULT_SHELL: &str = "cmd.exe";
/// A command that should be benchmarked.
#[derive(Debug, Clone)]
pub struct Command<'a> {
/// The command that should be executed (without parameter substitution)
expression: &'a str,
/// A possible parameter value.
parameter: Option<(&'a str, i32)>,
}
impl<'a> Command<'a> {
pub fn new(expression: &'a str) -> Command<'a> {
Command {
expression: expression,
parameter: None,
}
}
pub fn new_parametrized(expression: &'a str, parameter: &'a str, value: i32) -> Command<'a> {
Command {
expression: expression,
parameter: Some((parameter, value)),
}
}
pub fn get_shell_command(&self) -> String {
match self.parameter {
Some((param_name, param_value)) => self.expression.replace(
&format!("{{{param_name}}}", param_name = param_name),
¶m_value.to_string(),
),
None => self.expression.into(),
}
}
pub fn get_parameter(&self) -> Option<(&'a str, i32)> {
self.parameter
}
}
impl<'a> fmt::Display for Command<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.get_shell_command())
}
}
/// Action to take when an executed command fails.
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum CmdFailureAction {
/// Exit with an error message
RaiseError,
/// Simply ignore the non-zero exit code
Ignore,
}
/// Output style type option
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum OutputStyleOption {
/// Do not output with colors or any special formatting
Basic,
/// Output with full color and formatting
Full,
/// Keep elements such as progress bar, but use no coloring
NoColor,
/// Keep coloring, but use no progress bar
Color,
}
/// Number of runs for a benchmark
pub struct Runs {
/// Minimum number of benchmark runs
pub min: u64,
/// Maximum number of benchmark runs
pub max: Option<u64>,
}
impl Default for Runs {
fn default() -> Runs {
Runs { min: 10, max: None }
}
}
/// A set of options for hyperfine
pub struct HyperfineOptions {
/// Number of warmup runs
pub warmup_count: u64,
/// Number of benchmark runs
pub runs: Runs,
/// Minimum benchmarking time
pub min_time_sec: Second,
/// Whether or not to ignore non-zero exit codes
pub failure_action: CmdFailureAction,
/// Command to run before each timing run
pub preparation_command: Option<String>,
/// Command to run after each benchmark
pub cleanup_command: Option<String>,
/// What color mode to use for output
pub output_style: OutputStyleOption,
/// The shell to use for executing commands.
pub shell: String,
/// Forward benchmark's stdout to hyperfine's stdout
pub show_output: bool,
/// Which time unit to use for CLI & Markdown output
pub time_unit: Option<Unit>,
}
impl Default for HyperfineOptions {
fn default() -> HyperfineOptions {
HyperfineOptions {
warmup_count: 0,
runs: Runs::default(),
min_time_sec: 3.0,
failure_action: CmdFailureAction::RaiseError,
preparation_command: None,
cleanup_command: None,
output_style: OutputStyleOption::Full,
shell: DEFAULT_SHELL.to_string(),
show_output: false,
time_unit: None,
}
}
}
/// Set of values that will be exported.
#[derive(Debug, Default, Clone, Serialize)]
pub struct BenchmarkResult {
/// The command that was run
pub command: String,
/// The mean run time
pub mean: Second,
/// The standard deviation of all run times
pub stddev: Second,
/// Time spend in user space
pub user: Second,
/// Time spent in system space
pub system: Second,
/// Min time measured
pub min: Second,
/// Max time measured
pub max: Second,
/// All run time measurements
#[serde(skip_serializing_if = "Option::is_none")]
pub times: Option<Vec<Second>>,
/// Any parameter used
#[serde(skip_serializing_if = "Option::is_none")]
pub parameter: Option<i32>,
}
impl BenchmarkResult {
/// Create a new entry with the given values.
pub fn new(
command: String,
mean: Second,
stddev: Second,
user: Second,
system: Second,
min: Second,
max: Second,
times: Vec<Second>,
parameter: Option<i32>,
) -> Self {
BenchmarkResult {
command,
mean,
stddev,
user,
system,
min,
max,
times: Some(times),
parameter,
}
}
}