aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_prof
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-07-30 09:44:31 +0100
committerGitHub <[email protected]>2020-07-30 09:44:31 +0100
commit72ffd851dd5b0fcdf3aa072131ba11009878b4ae (patch)
tree4b35f683a6bfb70fa9e1db3b22371ebcde0e7d99 /crates/ra_prof
parentc8573c418cb5240e0b60e93b15978b00e3ff0683 (diff)
parentf22af66c3763c4b2a9d16621473cb6979fb2f36d (diff)
Merge #5581
5581: Measure instructions in addition to time r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_prof')
-rw-r--r--crates/ra_prof/Cargo.toml3
-rw-r--r--crates/ra_prof/src/lib.rs2
-rw-r--r--crates/ra_prof/src/stop_watch.rs79
3 files changed, 84 insertions, 0 deletions
diff --git a/crates/ra_prof/Cargo.toml b/crates/ra_prof/Cargo.toml
index 6c214501e..c82b9f76d 100644
--- a/crates/ra_prof/Cargo.toml
+++ b/crates/ra_prof/Cargo.toml
@@ -16,6 +16,9 @@ backtrace = { version = "0.3.44", optional = true }
16cfg-if = "0.1.10" 16cfg-if = "0.1.10"
17libc = "0.2.73" 17libc = "0.2.73"
18 18
19[target.'cfg(target_os = "linux")'.dependencies]
20perf-event = "0.4"
21
19[features] 22[features]
20cpu_profiler = [] 23cpu_profiler = []
21 24
diff --git a/crates/ra_prof/src/lib.rs b/crates/ra_prof/src/lib.rs
index ba5609703..eb50965ae 100644
--- a/crates/ra_prof/src/lib.rs
+++ b/crates/ra_prof/src/lib.rs
@@ -1,5 +1,6 @@
1//! A collection of tools for profiling rust-analyzer. 1//! A collection of tools for profiling rust-analyzer.
2 2
3mod stop_watch;
3mod memory_usage; 4mod memory_usage;
4#[cfg(feature = "cpu_profiler")] 5#[cfg(feature = "cpu_profiler")]
5mod google_cpu_profiler; 6mod google_cpu_profiler;
@@ -11,6 +12,7 @@ use std::cell::RefCell;
11pub use crate::{ 12pub use crate::{
12 hprof::{init, init_from, profile}, 13 hprof::{init, init_from, profile},
13 memory_usage::{Bytes, MemoryUsage}, 14 memory_usage::{Bytes, MemoryUsage},
15 stop_watch::{StopWatch, StopWatchSpan},
14}; 16};
15 17
16/// Prints backtrace to stderr, useful for debugging. 18/// Prints backtrace to stderr, useful for debugging.
diff --git a/crates/ra_prof/src/stop_watch.rs b/crates/ra_prof/src/stop_watch.rs
new file mode 100644
index 000000000..8b8ec25a5
--- /dev/null
+++ b/crates/ra_prof/src/stop_watch.rs
@@ -0,0 +1,79 @@
1//! Like `std::time::Instant`, but also measures memory & CPU cycles.
2use std::{
3 fmt,
4 time::{Duration, Instant},
5};
6
7use crate::MemoryUsage;
8
9pub struct StopWatch {
10 time: Instant,
11 #[cfg(target_os = "linux")]
12 counter: Option<perf_event::Counter>,
13 memory: Option<MemoryUsage>,
14}
15
16pub struct StopWatchSpan {
17 pub time: Duration,
18 pub instructions: Option<u64>,
19 pub memory: Option<MemoryUsage>,
20}
21
22impl StopWatch {
23 pub fn start() -> StopWatch {
24 #[cfg(target_os = "linux")]
25 let counter = {
26 let mut counter = perf_event::Builder::new().build().ok();
27 if let Some(counter) = &mut counter {
28 let _ = counter.enable();
29 }
30 counter
31 };
32 let time = Instant::now();
33 StopWatch {
34 time,
35 #[cfg(target_os = "linux")]
36 counter,
37 memory: None,
38 }
39 }
40 pub fn memory(mut self, yes: bool) -> StopWatch {
41 if yes {
42 self.memory = Some(MemoryUsage::current());
43 }
44 self
45 }
46 pub fn elapsed(&mut self) -> StopWatchSpan {
47 let time = self.time.elapsed();
48
49 #[cfg(target_os = "linux")]
50 let instructions = self.counter.as_mut().and_then(|it| it.read().ok());
51 #[cfg(not(target_os = "linux"))]
52 let instructions = None;
53
54 let memory = self.memory.map(|it| MemoryUsage::current() - it);
55 StopWatchSpan { time, instructions, memory }
56 }
57}
58
59impl fmt::Display for StopWatchSpan {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 write!(f, "{:.2?}", self.time)?;
62 if let Some(mut instructions) = self.instructions {
63 let mut prefix = "";
64 if instructions > 10000 {
65 instructions /= 1000;
66 prefix = "k"
67 }
68 if instructions > 10000 {
69 instructions /= 1000;
70 prefix = "m"
71 }
72 write!(f, ", {}{}i", instructions, prefix)?;
73 }
74 if let Some(memory) = self.memory {
75 write!(f, ", {}", memory)?;
76 }
77 Ok(())
78 }
79}