aboutsummaryrefslogtreecommitdiff
path: root/xtask
diff options
context:
space:
mode:
Diffstat (limited to 'xtask')
-rw-r--r--xtask/src/metrics.rs55
-rw-r--r--xtask/src/not_bash.rs3
2 files changed, 48 insertions, 10 deletions
diff --git a/xtask/src/metrics.rs b/xtask/src/metrics.rs
index 6c042d695..9ac3fa51d 100644
--- a/xtask/src/metrics.rs
+++ b/xtask/src/metrics.rs
@@ -3,14 +3,15 @@ use std::{
3 env, 3 env,
4 fmt::{self, Write as _}, 4 fmt::{self, Write as _},
5 io::Write as _, 5 io::Write as _,
6 path::Path,
6 time::{Instant, SystemTime, UNIX_EPOCH}, 7 time::{Instant, SystemTime, UNIX_EPOCH},
7}; 8};
8 9
9use anyhow::{bail, format_err, Result}; 10use anyhow::{bail, format_err, Result};
10 11
11use crate::not_bash::{fs2, pushd, rm_rf, run}; 12use crate::not_bash::{fs2, pushd, pushenv, rm_rf, run};
12 13
13type Unit = &'static str; 14type Unit = String;
14 15
15pub struct MetricsCmd { 16pub struct MetricsCmd {
16 pub dry_run: bool, 17 pub dry_run: bool,
@@ -22,9 +23,21 @@ impl MetricsCmd {
22 if !self.dry_run { 23 if !self.dry_run {
23 rm_rf("./target/release")?; 24 rm_rf("./target/release")?;
24 } 25 }
26 if !Path::new("./target/rustc-perf").exists() {
27 fs2::create_dir_all("./target/rustc-perf")?;
28 run!("git clone https://github.com/rust-lang/rustc-perf.git ./target/rustc-perf")?;
29 }
30 {
31 let _d = pushd("./target/rustc-perf");
32 run!("git reset --hard 1d9288b0da7febf2599917da1b57dc241a1af033")?;
33 }
34
35 let _env = pushenv("RA_METRICS", "1");
25 36
26 metrics.measure_build()?; 37 metrics.measure_build()?;
27 metrics.measure_analysis_stats_self()?; 38 metrics.measure_analysis_stats_self()?;
39 metrics.measure_analysis_stats("ripgrep")?;
40 metrics.measure_analysis_stats("webrender")?;
28 41
29 if !self.dry_run { 42 if !self.dry_run {
30 let _d = pushd("target"); 43 let _d = pushd("target");
@@ -46,23 +59,47 @@ impl MetricsCmd {
46 59
47impl Metrics { 60impl Metrics {
48 fn measure_build(&mut self) -> Result<()> { 61 fn measure_build(&mut self) -> Result<()> {
62 eprintln!("\nMeasuring build");
49 run!("cargo fetch")?; 63 run!("cargo fetch")?;
50 64
51 let time = Instant::now(); 65 let time = Instant::now();
52 run!("cargo build --release --package rust-analyzer --bin rust-analyzer")?; 66 run!("cargo build --release --package rust-analyzer --bin rust-analyzer")?;
53 let time = time.elapsed(); 67 let time = time.elapsed();
54 self.report("build", time.as_millis() as u64, "ms"); 68 self.report("build", time.as_millis() as u64, "ms".into());
55 Ok(()) 69 Ok(())
56 } 70 }
57 fn measure_analysis_stats_self(&mut self) -> Result<()> { 71 fn measure_analysis_stats_self(&mut self) -> Result<()> {
58 let time = Instant::now(); 72 self.measure_analysis_stats_path("self", &".")
59 run!("./target/release/rust-analyzer analysis-stats .")?; 73 }
60 let time = time.elapsed(); 74 fn measure_analysis_stats(&mut self, bench: &str) -> Result<()> {
61 self.report("analysis-stats/self", time.as_millis() as u64, "ms"); 75 self.measure_analysis_stats_path(
76 bench,
77 &format!("./target/rustc-perf/collector/benchmarks/{}", bench),
78 )
79 }
80 fn measure_analysis_stats_path(&mut self, name: &str, path: &str) -> Result<()> {
81 eprintln!("\nMeasuring analysis-stats/{}", name);
82 let output = run!("./target/release/rust-analyzer analysis-stats --quiet {}", path)?;
83 for (metric, value, unit) in parse_metrics(&output) {
84 self.report(&format!("analysis-stats/{}/{}", name, metric), value, unit.into());
85 }
62 Ok(()) 86 Ok(())
63 } 87 }
64} 88}
65 89
90fn parse_metrics(output: &str) -> Vec<(&str, u64, &str)> {
91 output
92 .lines()
93 .filter_map(|it| {
94 let entry = it.split(':').collect::<Vec<_>>();
95 match entry.as_slice() {
96 ["METRIC", name, value, unit] => Some((*name, value.parse().unwrap(), *unit)),
97 _ => None,
98 }
99 })
100 .collect()
101}
102
66#[derive(Debug)] 103#[derive(Debug)]
67struct Metrics { 104struct Metrics {
68 host: Host, 105 host: Host,
@@ -111,11 +148,11 @@ impl Metrics {
111 json.field("metrics"); 148 json.field("metrics");
112 json.begin_object(); 149 json.begin_object();
113 { 150 {
114 for (k, &(value, unit)) in &self.metrics { 151 for (k, (value, unit)) in &self.metrics {
115 json.field(k); 152 json.field(k);
116 json.begin_array(); 153 json.begin_array();
117 { 154 {
118 json.number(value as f64); 155 json.number(*value as f64);
119 json.string(unit); 156 json.string(unit);
120 } 157 }
121 json.end_array(); 158 json.end_array();
diff --git a/xtask/src/not_bash.rs b/xtask/src/not_bash.rs
index 0f3a56b25..ef811e5bf 100644
--- a/xtask/src/not_bash.rs
+++ b/xtask/src/not_bash.rs
@@ -186,7 +186,8 @@ impl Env {
186 fn pushd(&mut self, dir: PathBuf) { 186 fn pushd(&mut self, dir: PathBuf) {
187 let dir = self.cwd().join(dir); 187 let dir = self.cwd().join(dir);
188 self.pushd_stack.push(dir); 188 self.pushd_stack.push(dir);
189 env::set_current_dir(self.cwd()).unwrap(); 189 env::set_current_dir(self.cwd())
190 .unwrap_or_else(|err| panic!("Failed to set cwd to {}: {}", self.cwd().display(), err));
190 } 191 }
191 fn popd(&mut self) { 192 fn popd(&mut self) {
192 self.pushd_stack.pop().unwrap(); 193 self.pushd_stack.pop().unwrap();