aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_prof/src/stop_watch.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_prof/src/stop_watch.rs')
-rw-r--r--crates/ra_prof/src/stop_watch.rs72
1 files changed, 72 insertions, 0 deletions
diff --git a/crates/ra_prof/src/stop_watch.rs b/crates/ra_prof/src/stop_watch.rs
new file mode 100644
index 000000000..54bfb0559
--- /dev/null
+++ b/crates/ra_prof/src/stop_watch.rs
@@ -0,0 +1,72 @@
1use crate::MemoryUsage;
2use std::{
3 fmt,
4 time::{Duration, Instant},
5};
6
7pub struct StopWatch {
8 time: Instant,
9 counter: Option<perf_event::Counter>,
10 memory: Option<MemoryUsage>,
11}
12
13pub struct StopWatchSpan {
14 pub time: Duration,
15 pub instructions: Option<u64>,
16 pub memory: Option<MemoryUsage>,
17}
18
19impl StopWatch {
20 pub fn start() -> StopWatch {
21 let mut counter = perf_event::Builder::new().build().ok();
22 if let Some(counter) = &mut counter {
23 let _ = counter.enable();
24 }
25 let time = Instant::now();
26 StopWatch { time, counter, memory: None }
27 }
28 pub fn memory(mut self, yes: bool) -> StopWatch {
29 if yes {
30 self.memory = Some(MemoryUsage::current());
31 }
32 self
33 }
34 pub fn elapsed(&mut self) -> StopWatchSpan {
35 let time = self.time.elapsed();
36 let instructions = self.counter.as_mut().and_then(|it| it.read().ok());
37 let memory = self.memory.map(|it| MemoryUsage::current() - it);
38 StopWatchSpan { time, instructions, memory }
39 }
40}
41
42impl fmt::Display for StopWatchSpan {
43 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44 write!(f, "{:.2?}", self.time)?;
45 if let Some(mut instructions) = self.instructions {
46 let mut prefix = "";
47 if instructions > 10000 {
48 instructions /= 1000;
49 prefix = "k"
50 }
51 if instructions > 10000 {
52 instructions /= 1000;
53 prefix = "m"
54 }
55 write!(f, ", {}{}i", instructions, prefix)?;
56 }
57 if let Some(memory) = self.memory {
58 write!(f, ", {}", memory)?;
59 }
60 Ok(())
61 }
62}
63
64// Unclear if we need this:
65// https://github.com/jimblandy/perf-event/issues/8
66impl Drop for StopWatch {
67 fn drop(&mut self) {
68 if let Some(mut counter) = self.counter.take() {
69 let _ = counter.disable();
70 }
71 }
72}