Skip to content

Commit 48f9a05

Browse files
bors[bot]matklad
andauthored
Merge #5531
5531: Add rustc-perf to metrics r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
2 parents 0a4e90c + 451edcc commit 48f9a05

File tree

6 files changed

+102
-30
lines changed

6 files changed

+102
-30
lines changed

crates/ra_prof/src/memory_usage.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ impl fmt::Display for MemoryUsage {
3131
#[derive(Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
3232
pub struct Bytes(usize);
3333

34+
impl Bytes {
35+
pub fn megabytes(self) -> usize {
36+
self.0 / 1024 / 1024
37+
}
38+
}
39+
3440
impl fmt::Display for Bytes {
3541
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3642
let bytes = self.0;

crates/rust-analyzer/src/cli.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,10 @@ fn read_stdin() -> Result<String> {
7474
std::io::stdin().read_to_string(&mut buff)?;
7575
Ok(buff)
7676
}
77+
78+
fn report_metric(metric: &str, value: u64, unit: &str) {
79+
if std::env::var("RA_METRICS").is_err() {
80+
return;
81+
}
82+
println!("METRIC:{}:{}:{}", metric, value, unit)
83+
}

crates/rust-analyzer/src/cli/analysis_stats.rs

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,27 @@
33
44
use std::{path::Path, time::Instant};
55

6-
use itertools::Itertools;
7-
use rand::{seq::SliceRandom, thread_rng};
8-
use rayon::prelude::*;
9-
use rustc_hash::FxHashSet;
10-
116
use hir::{
127
db::{AstDatabase, DefDatabase, HirDatabase},
138
original_range, AssocItem, Crate, HasSource, HirDisplay, ModuleDef,
149
};
1510
use hir_def::FunctionId;
1611
use hir_ty::{Ty, TypeWalk};
12+
use itertools::Itertools;
1713
use ra_db::{
1814
salsa::{self, ParallelDatabase},
1915
SourceDatabaseExt,
2016
};
2117
use ra_syntax::AstNode;
18+
use rand::{seq::SliceRandom, thread_rng};
19+
use rayon::prelude::*;
20+
use rustc_hash::FxHashSet;
2221
use stdx::format_to;
2322

2423
use crate::{
25-
cli::{load_cargo::load_cargo, progress_report::ProgressReport, Result, Verbosity},
24+
cli::{
25+
load_cargo::load_cargo, progress_report::ProgressReport, report_metric, Result, Verbosity,
26+
},
2627
print_memory_usage,
2728
};
2829

@@ -48,7 +49,7 @@ pub fn analysis_stats(
4849
let db_load_time = Instant::now();
4950
let (host, vfs) = load_cargo(path, load_output_dirs, with_proc_macro)?;
5051
let db = host.raw_database();
51-
println!("Database loaded {:?}", db_load_time.elapsed());
52+
eprintln!("Database loaded {:?}", db_load_time.elapsed());
5253
let analysis_time = Instant::now();
5354
let mut num_crates = 0;
5455
let mut visited_modules = FxHashSet::default();
@@ -74,7 +75,7 @@ pub fn analysis_stats(
7475
visit_queue.shuffle(&mut thread_rng());
7576
}
7677

77-
println!("Crates in this dir: {}", num_crates);
78+
eprintln!("Crates in this dir: {}", num_crates);
7879
let mut num_decls = 0;
7980
let mut funcs = Vec::new();
8081
while let Some(module) = visit_queue.pop() {
@@ -98,10 +99,15 @@ pub fn analysis_stats(
9899
}
99100
}
100101
}
101-
println!("Total modules found: {}", visited_modules.len());
102-
println!("Total declarations: {}", num_decls);
103-
println!("Total functions: {}", funcs.len());
104-
println!("Item Collection: {:?}, {}", analysis_time.elapsed(), ra_prof::memory_usage());
102+
eprintln!("Total modules found: {}", visited_modules.len());
103+
eprintln!("Total declarations: {}", num_decls);
104+
eprintln!("Total functions: {}", funcs.len());
105+
let item_collection_memory = ra_prof::memory_usage();
106+
eprintln!(
107+
"Item Collection: {:?}, {}",
108+
analysis_time.elapsed(),
109+
item_collection_memory.allocated
110+
);
105111

106112
if randomize {
107113
funcs.shuffle(&mut thread_rng());
@@ -123,7 +129,11 @@ pub fn analysis_stats(
123129
snap.0.infer(f_id.into());
124130
})
125131
.count();
126-
println!("Parallel Inference: {:?}, {}", inference_time.elapsed(), ra_prof::memory_usage());
132+
eprintln!(
133+
"Parallel Inference: {:?}, {}",
134+
inference_time.elapsed(),
135+
ra_prof::memory_usage().allocated
136+
);
127137
}
128138

129139
let inference_time = Instant::now();
@@ -260,20 +270,31 @@ pub fn analysis_stats(
260270
bar.inc(1);
261271
}
262272
bar.finish_and_clear();
263-
println!("Total expressions: {}", num_exprs);
264-
println!(
273+
eprintln!("Total expressions: {}", num_exprs);
274+
eprintln!(
265275
"Expressions of unknown type: {} ({}%)",
266276
num_exprs_unknown,
267277
if num_exprs > 0 { num_exprs_unknown * 100 / num_exprs } else { 100 }
268278
);
269-
println!(
279+
eprintln!(
270280
"Expressions of partially unknown type: {} ({}%)",
271281
num_exprs_partially_unknown,
272282
if num_exprs > 0 { num_exprs_partially_unknown * 100 / num_exprs } else { 100 }
273283
);
274-
println!("Type mismatches: {}", num_type_mismatches);
275-
println!("Inference: {:?}, {}", inference_time.elapsed(), ra_prof::memory_usage());
276-
println!("Total: {:?}, {}", analysis_time.elapsed(), ra_prof::memory_usage());
284+
eprintln!("Type mismatches: {}", num_type_mismatches);
285+
286+
let inference_time = inference_time.elapsed();
287+
let total_memory = ra_prof::memory_usage();
288+
eprintln!(
289+
"Inference: {:?}, {}",
290+
inference_time,
291+
total_memory.allocated - item_collection_memory.allocated
292+
);
293+
294+
let analysis_time = analysis_time.elapsed();
295+
eprintln!("Total: {:?}, {}", analysis_time, total_memory);
296+
report_metric("total time", analysis_time.as_millis() as u64, "ms");
297+
report_metric("total memory", total_memory.allocated.megabytes() as u64, "MB");
277298

278299
if memory_usage {
279300
print_memory_usage(host, vfs);

crates/rust-analyzer/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,6 @@ fn print_memory_usage(mut host: AnalysisHost, vfs: Vfs) {
8686
mem.push(("Remaining".into(), ra_prof::memory_usage().allocated));
8787

8888
for (name, bytes) in mem {
89-
println!("{:>8} {}", bytes, name);
89+
eprintln!("{:>8} {}", bytes, name);
9090
}
9191
}

xtask/src/metrics.rs

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ use std::{
33
env,
44
fmt::{self, Write as _},
55
io::Write as _,
6+
path::Path,
67
time::{Instant, SystemTime, UNIX_EPOCH},
78
};
89

910
use anyhow::{bail, format_err, Result};
1011

11-
use crate::not_bash::{fs2, pushd, rm_rf, run};
12+
use crate::not_bash::{fs2, pushd, pushenv, rm_rf, run};
1213

13-
type Unit = &'static str;
14+
type Unit = String;
1415

1516
pub struct MetricsCmd {
1617
pub dry_run: bool,
@@ -22,9 +23,21 @@ impl MetricsCmd {
2223
if !self.dry_run {
2324
rm_rf("./target/release")?;
2425
}
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");
2536

2637
metrics.measure_build()?;
2738
metrics.measure_analysis_stats_self()?;
39+
metrics.measure_analysis_stats("ripgrep")?;
40+
metrics.measure_analysis_stats("webrender")?;
2841

2942
if !self.dry_run {
3043
let _d = pushd("target");
@@ -46,23 +59,47 @@ impl MetricsCmd {
4659

4760
impl Metrics {
4861
fn measure_build(&mut self) -> Result<()> {
62+
eprintln!("\nMeasuring build");
4963
run!("cargo fetch")?;
5064

5165
let time = Instant::now();
5266
run!("cargo build --release --package rust-analyzer --bin rust-analyzer")?;
5367
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());
5569
Ok(())
5670
}
5771
fn measure_analysis_stats_self(&mut self) -> Result<()> {
58-
let time = Instant::now();
59-
run!("./target/release/rust-analyzer analysis-stats .")?;
60-
let time = time.elapsed();
61-
self.report("analysis-stats/self", time.as_millis() as u64, "ms");
72+
self.measure_analysis_stats_path("self", &".")
73+
}
74+
fn measure_analysis_stats(&mut self, bench: &str) -> Result<()> {
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+
}
6286
Ok(())
6387
}
6488
}
6589

90+
fn 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+
66103
#[derive(Debug)]
67104
struct Metrics {
68105
host: Host,
@@ -111,11 +148,11 @@ impl Metrics {
111148
json.field("metrics");
112149
json.begin_object();
113150
{
114-
for (k, &(value, unit)) in &self.metrics {
151+
for (k, (value, unit)) in &self.metrics {
115152
json.field(k);
116153
json.begin_array();
117154
{
118-
json.number(value as f64);
155+
json.number(*value as f64);
119156
json.string(unit);
120157
}
121158
json.end_array();

xtask/src/not_bash.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,8 @@ impl Env {
186186
fn pushd(&mut self, dir: PathBuf) {
187187
let dir = self.cwd().join(dir);
188188
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));
190191
}
191192
fn popd(&mut self) {
192193
self.pushd_stack.pop().unwrap();

0 commit comments

Comments
 (0)