Skip to content

Commit 797185e

Browse files
committed
internal: switch from CLI to internal benchmarking
We have a CLI for benchmarking, but no one actually uses it it seems. Let's try switching to "internal" benchmarks, implemented as rust tests. They should be easier to "script" to automate tracking of perf regressions.
1 parent 904bdff commit 797185e

File tree

6 files changed

+76
-262
lines changed

6 files changed

+76
-262
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
//! Fully integrated benchmarks for rust-analyzer, which load real cargo
2+
//! projects.
3+
//!
4+
//! The benchmark here is used to debug specific performance regressions. If you
5+
//! notice that, eg, completion is slow in some specific case, you can modify
6+
//! code here exercise this specific completion, and thus have a fast
7+
//! edit/compile/test cycle.
8+
//!
9+
//! Note that "Rust Analyzer: Run" action does not allow running a single test
10+
//! in release mode in VS Code. There's however "Rust Analyzer: Copy Run Command Line"
11+
//! which you can use to paste the command in terminal and add `--release` manually.
12+
13+
use std::sync::Arc;
14+
15+
use ide::Change;
16+
use test_utils::project_root;
17+
use vfs::{AbsPathBuf, VfsPath};
18+
19+
use crate::cli::load_cargo::{load_workspace_at, LoadCargoConfig};
20+
21+
#[test]
22+
fn benchmark_integrated_highlighting() {
23+
// Don't run slow benchmark by default
24+
if true {
25+
return;
26+
}
27+
28+
// Load rust-analyzer itself.
29+
let workspace_to_load = project_root();
30+
let file = "./crates/ide_db/src/apply_change.rs";
31+
32+
let cargo_config = Default::default();
33+
let load_cargo_config =
34+
LoadCargoConfig { load_out_dirs_from_check: true, with_proc_macro: false };
35+
36+
let (mut host, vfs, _proc_macro) = {
37+
let _it = stdx::timeit("workspace loading");
38+
load_workspace_at(&workspace_to_load, &cargo_config, &load_cargo_config, &|_| {}).unwrap()
39+
};
40+
41+
let file_id = {
42+
let file = workspace_to_load.join(file);
43+
let path = VfsPath::from(AbsPathBuf::assert(file));
44+
vfs.file_id(&path).unwrap_or_else(|| panic!("can't find virtual file for {}", path))
45+
};
46+
47+
{
48+
let _it = stdx::timeit("initial");
49+
let analysis = host.analysis();
50+
analysis.highlight_as_html(file_id, false).unwrap();
51+
}
52+
53+
profile::init_from("*>100");
54+
55+
{
56+
let _it = stdx::timeit("change");
57+
let mut text = host.analysis().file_text(file_id).unwrap().to_string();
58+
text.push_str("\npub fn _dummy() {}\n");
59+
let mut change = Change::new();
60+
change.change_file(file_id, Some(Arc::new(text)));
61+
host.apply_change(change);
62+
}
63+
64+
{
65+
let _it = stdx::timeit("after change");
66+
let analysis = host.analysis();
67+
analysis.highlight_as_html(file_id, false).unwrap();
68+
}
69+
}

crates/rust-analyzer/src/bin/flags.rs

Lines changed: 2 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
//! Grammar for the command-line arguments.
22
#![allow(unreachable_pub)]
3-
use std::{env, path::PathBuf};
3+
use std::path::PathBuf;
44

55
use ide_ssr::{SsrPattern, SsrRule};
6-
use rust_analyzer::cli::{BenchWhat, Position, Verbosity};
7-
use vfs::AbsPathBuf;
6+
use rust_analyzer::cli::Verbosity;
87

98
xflags::xflags! {
109
src "./src/bin/flags.rs"
@@ -74,27 +73,6 @@ xflags::xflags! {
7473
optional --with-proc-macro
7574
}
7675

77-
/// Benchmark specific analysis operation
78-
cmd analysis-bench
79-
/// Directory with Cargo.toml.
80-
required path: PathBuf
81-
{
82-
/// Collect memory usage statistics.
83-
optional --memory-usage
84-
85-
/// Compute syntax highlighting for this file
86-
optional --highlight path: PathBuf
87-
/// Compute completions at file:line:column location.
88-
optional --complete location: Position
89-
/// Compute goto definition at file:line:column location.
90-
optional --goto-def location: Position
91-
92-
/// Load OUT_DIR values by running `cargo check` before analysis.
93-
optional --load-output-dirs
94-
/// Use proc-macro-srv for proc-macro expanding.
95-
optional --with-proc-macro
96-
}
97-
9876
cmd diagnostics
9977
/// Directory with Cargo.toml.
10078
required path: PathBuf
@@ -142,7 +120,6 @@ pub enum RustAnalyzerCmd {
142120
Symbols(Symbols),
143121
Highlight(Highlight),
144122
AnalysisStats(AnalysisStats),
145-
AnalysisBench(AnalysisBench),
146123
Diagnostics(Diagnostics),
147124
Ssr(Ssr),
148125
Search(Search),
@@ -183,18 +160,6 @@ pub struct AnalysisStats {
183160
pub with_proc_macro: bool,
184161
}
185162

186-
#[derive(Debug)]
187-
pub struct AnalysisBench {
188-
pub path: PathBuf,
189-
190-
pub memory_usage: bool,
191-
pub highlight: Option<PathBuf>,
192-
pub complete: Option<Position>,
193-
pub goto_def: Option<Position>,
194-
pub load_output_dirs: bool,
195-
pub with_proc_macro: bool,
196-
}
197-
198163
#[derive(Debug)]
199164
pub struct Diagnostics {
200165
pub path: PathBuf,
@@ -239,17 +204,3 @@ impl RustAnalyzer {
239204
}
240205
}
241206
}
242-
243-
impl AnalysisBench {
244-
pub(crate) fn what(&self) -> BenchWhat {
245-
match (&self.highlight, &self.complete, &self.goto_def) {
246-
(Some(path), None, None) => {
247-
let path = env::current_dir().unwrap().join(path);
248-
BenchWhat::Highlight { path: AbsPathBuf::assert(path) }
249-
}
250-
(None, Some(position), None) => BenchWhat::Complete(position.clone()),
251-
(None, None, Some(position)) => BenchWhat::GotoDef(position.clone()),
252-
_ => panic!("exactly one of `--highlight`, `--complete` or `--goto-def` must be set"),
253-
}
254-
}
255-
}

crates/rust-analyzer/src/bin/main.rs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::{convert::TryFrom, env, fs, path::Path, process};
99
use lsp_server::Connection;
1010
use project_model::ProjectManifest;
1111
use rust_analyzer::{
12-
cli::{self, AnalysisStatsCmd, BenchCmd},
12+
cli::{self, AnalysisStatsCmd},
1313
config::Config,
1414
from_json,
1515
lsp_ext::supports_utf8,
@@ -80,17 +80,6 @@ fn try_main() -> Result<()> {
8080
with_proc_macro: cmd.with_proc_macro,
8181
}
8282
.run(verbosity)?,
83-
flags::RustAnalyzerCmd::AnalysisBench(cmd) => {
84-
let what = cmd.what();
85-
BenchCmd {
86-
memory_usage: cmd.memory_usage,
87-
path: cmd.path,
88-
load_output_dirs: cmd.load_output_dirs,
89-
with_proc_macro: cmd.with_proc_macro,
90-
what,
91-
}
92-
.run(verbosity)?
93-
}
9483

9584
flags::RustAnalyzerCmd::Diagnostics(cmd) => {
9685
cli::diagnostics(&cmd.path, cmd.load_output_dirs, cmd.with_proc_macro)?

crates/rust-analyzer/src/cli.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
//! Various batch processing tasks, intended primarily for debugging.
22
3-
mod load_cargo;
3+
pub(crate) mod load_cargo;
44
mod analysis_stats;
5-
mod analysis_bench;
65
mod diagnostics;
76
mod progress_report;
87
mod ssr;
@@ -15,7 +14,6 @@ use syntax::{AstNode, SourceFile};
1514
use vfs::Vfs;
1615

1716
pub use self::{
18-
analysis_bench::{BenchCmd, BenchWhat, Position},
1917
analysis_stats::AnalysisStatsCmd,
2018
diagnostics::diagnostics,
2119
load_cargo::{load_workspace, load_workspace_at, LoadCargoConfig},

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

Lines changed: 0 additions & 196 deletions
This file was deleted.

0 commit comments

Comments
 (0)