aboutsummaryrefslogtreecommitdiff
path: root/crates/rust-analyzer/src/cli/analysis_bench.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/rust-analyzer/src/cli/analysis_bench.rs')
-rw-r--r--crates/rust-analyzer/src/cli/analysis_bench.rs196
1 files changed, 0 insertions, 196 deletions
diff --git a/crates/rust-analyzer/src/cli/analysis_bench.rs b/crates/rust-analyzer/src/cli/analysis_bench.rs
deleted file mode 100644
index 49994824f..000000000
--- a/crates/rust-analyzer/src/cli/analysis_bench.rs
+++ /dev/null
@@ -1,196 +0,0 @@
1//! Benchmark operations like highlighting or goto definition.
2
3use std::{env, path::PathBuf, str::FromStr, sync::Arc, time::Instant};
4
5use anyhow::{bail, format_err, Result};
6use hir::PrefixKind;
7use ide::{
8 Analysis, AnalysisHost, Change, CompletionConfig, DiagnosticsConfig, FilePosition, LineCol,
9};
10use ide_db::{
11 base_db::{
12 salsa::{Database, Durability},
13 FileId,
14 },
15 helpers::{insert_use::InsertUseConfig, SnippetCap},
16};
17use vfs::AbsPathBuf;
18
19use crate::cli::{
20 load_cargo::{load_workspace_at, LoadCargoConfig},
21 print_memory_usage, Verbosity,
22};
23
24pub struct BenchCmd {
25 pub path: PathBuf,
26 pub what: BenchWhat,
27 pub memory_usage: bool,
28 pub load_output_dirs: bool,
29 pub with_proc_macro: bool,
30}
31
32pub enum BenchWhat {
33 Highlight { path: AbsPathBuf },
34 Complete(Position),
35 GotoDef(Position),
36}
37
38#[derive(Debug, Clone)]
39pub struct Position {
40 pub path: AbsPathBuf,
41 pub line: u32,
42 pub column: u32,
43}
44
45impl FromStr for Position {
46 type Err = anyhow::Error;
47 fn from_str(s: &str) -> Result<Self> {
48 let mut split = s.rsplitn(3, ':');
49 match (split.next(), split.next(), split.next()) {
50 (Some(column), Some(line), Some(path)) => {
51 let path = env::current_dir().unwrap().join(path);
52 let path = AbsPathBuf::assert(path);
53 Ok(Position { path, line: line.parse()?, column: column.parse()? })
54 }
55 _ => bail!("position should be in file:line:column format: {:?}", s),
56 }
57 }
58}
59
60impl BenchCmd {
61 pub fn run(self, verbosity: Verbosity) -> Result<()> {
62 profile::init();
63
64 let start = Instant::now();
65 eprint!("loading: ");
66
67 let cargo_config = Default::default();
68 let load_cargo_config = LoadCargoConfig {
69 load_out_dirs_from_check: self.load_output_dirs,
70 with_proc_macro: self.with_proc_macro,
71 };
72 let (mut host, vfs, _proc_macro) =
73 load_workspace_at(&self.path, &cargo_config, &load_cargo_config, &|_| {})?;
74 eprintln!("{:?}\n", start.elapsed());
75
76 let file_id = {
77 let path = match &self.what {
78 BenchWhat::Highlight { path } => path,
79 BenchWhat::Complete(pos) | BenchWhat::GotoDef(pos) => &pos.path,
80 };
81 let path = path.clone().into();
82 vfs.file_id(&path).ok_or_else(|| format_err!("Can't find {}", path))?
83 };
84
85 match &self.what {
86 BenchWhat::Highlight { .. } => {
87 let res = do_work(&mut host, file_id, |analysis| {
88 analysis.diagnostics(&DiagnosticsConfig::default(), file_id).unwrap();
89 analysis.highlight_as_html(file_id, false).unwrap()
90 });
91 if verbosity.is_verbose() {
92 println!("\n{}", res);
93 }
94 }
95 BenchWhat::Complete(pos) | BenchWhat::GotoDef(pos) => {
96 let is_completion = matches!(self.what, BenchWhat::Complete(..));
97
98 let offset = host
99 .analysis()
100 .file_line_index(file_id)?
101 .offset(LineCol { line: pos.line - 1, col: pos.column });
102 let file_position = FilePosition { file_id, offset };
103
104 if is_completion {
105 let options = CompletionConfig {
106 enable_postfix_completions: true,
107 enable_imports_on_the_fly: true,
108 add_call_parenthesis: true,
109 add_call_argument_snippets: true,
110 snippet_cap: SnippetCap::new(true),
111 insert_use: InsertUseConfig {
112 merge: None,
113 prefix_kind: PrefixKind::Plain,
114 group: true,
115 },
116 };
117 let res = do_work(&mut host, file_id, |analysis| {
118 analysis.completions(&options, file_position)
119 });
120 if verbosity.is_verbose() {
121 println!("\n{:#?}", res);
122 }
123 } else {
124 let res = do_work(&mut host, file_id, |analysis| {
125 analysis.goto_definition(file_position)
126 });
127 if verbosity.is_verbose() {
128 println!("\n{:#?}", res);
129 }
130 }
131 }
132 }
133
134 if self.memory_usage {
135 print_memory_usage(host, vfs);
136 }
137
138 Ok(())
139 }
140}
141
142fn do_work<F: Fn(&Analysis) -> T, T>(host: &mut AnalysisHost, file_id: FileId, work: F) -> T {
143 {
144 let start = Instant::now();
145 eprint!("from scratch: ");
146 work(&host.analysis());
147 eprintln!("{:?}", start.elapsed());
148 }
149 {
150 let start = Instant::now();
151 eprint!("no change: ");
152 work(&host.analysis());
153 eprintln!("{:?}", start.elapsed());
154 }
155 {
156 let start = Instant::now();
157 eprint!("trivial change: ");
158 host.raw_database_mut().salsa_runtime_mut().synthetic_write(Durability::LOW);
159 work(&host.analysis());
160 eprintln!("{:?}", start.elapsed());
161 }
162 {
163 let start = Instant::now();
164 eprint!("comment change: ");
165 {
166 let mut text = host.analysis().file_text(file_id).unwrap().to_string();
167 text.push_str("\n/* Hello world */\n");
168 let mut change = Change::new();
169 change.change_file(file_id, Some(Arc::new(text)));
170 host.apply_change(change);
171 }
172 work(&host.analysis());
173 eprintln!("{:?}", start.elapsed());
174 }
175 {
176 let start = Instant::now();
177 eprint!("item change: ");
178 {
179 let mut text = host.analysis().file_text(file_id).unwrap().to_string();
180 text.push_str("\npub fn _dummy() {}\n");
181 let mut change = Change::new();
182 change.change_file(file_id, Some(Arc::new(text)));
183 host.apply_change(change);
184 }
185 work(&host.analysis());
186 eprintln!("{:?}", start.elapsed());
187 }
188 {
189 let start = Instant::now();
190 eprint!("const change: ");
191 host.raw_database_mut().salsa_runtime_mut().synthetic_write(Durability::HIGH);
192 let res = work(&host.analysis());
193 eprintln!("{:?}", start.elapsed());
194 res
195 }
196}