]> git.proxmox.com Git - rustc.git/blame - src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs
New upstream version 1.68.2+dfsg1
[rustc.git] / src / tools / rust-analyzer / crates / rust-analyzer / src / integrated_benchmarks.rs
CommitLineData
064997fb
FG
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//!
f2b60f7d
FG
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"
064997fb
FG
11//! which you can use to paste the command in terminal and add `--release` manually.
12
13use std::sync::Arc;
14
15use ide::{CallableSnippets, Change, CompletionConfig, FilePosition, TextSize};
16use ide_db::{
17 imports::insert_use::{ImportGranularity, InsertUseConfig},
18 SnippetCap,
19};
20use project_model::CargoConfig;
21use test_utils::project_root;
22use vfs::{AbsPathBuf, VfsPath};
23
24use crate::cli::load_cargo::{load_workspace_at, LoadCargoConfig};
25
26#[test]
27fn integrated_highlighting_benchmark() {
28 if std::env::var("RUN_SLOW_BENCHES").is_err() {
29 return;
30 }
31
32 // Load rust-analyzer itself.
33 let workspace_to_load = project_root();
34 let file = "./crates/ide-db/src/apply_change.rs";
35
36 let cargo_config = CargoConfig::default();
37 let load_cargo_config = LoadCargoConfig {
38 load_out_dirs_from_check: true,
39 with_proc_macro: false,
40 prefill_caches: false,
41 };
42
43 let (mut host, vfs, _proc_macro) = {
44 let _it = stdx::timeit("workspace loading");
45 load_workspace_at(&workspace_to_load, &cargo_config, &load_cargo_config, &|_| {}).unwrap()
46 };
47
48 let file_id = {
49 let file = workspace_to_load.join(file);
50 let path = VfsPath::from(AbsPathBuf::assert(file));
9c376795 51 vfs.file_id(&path).unwrap_or_else(|| panic!("can't find virtual file for {path}"))
064997fb
FG
52 };
53
54 {
55 let _it = stdx::timeit("initial");
56 let analysis = host.analysis();
57 analysis.highlight_as_html(file_id, false).unwrap();
58 }
59
60 profile::init_from("*>100");
61 // let _s = profile::heartbeat_span();
62
63 {
64 let _it = stdx::timeit("change");
65 let mut text = host.analysis().file_text(file_id).unwrap().to_string();
66 text.push_str("\npub fn _dummy() {}\n");
67 let mut change = Change::new();
68 change.change_file(file_id, Some(Arc::new(text)));
69 host.apply_change(change);
70 }
71
72 {
73 let _it = stdx::timeit("after change");
74 let _span = profile::cpu_span();
75 let analysis = host.analysis();
76 analysis.highlight_as_html(file_id, false).unwrap();
77 }
78}
79
80#[test]
81fn integrated_completion_benchmark() {
82 if std::env::var("RUN_SLOW_BENCHES").is_err() {
83 return;
84 }
85
86 // Load rust-analyzer itself.
87 let workspace_to_load = project_root();
88 let file = "./crates/hir/src/lib.rs";
89
90 let cargo_config = CargoConfig::default();
91 let load_cargo_config = LoadCargoConfig {
92 load_out_dirs_from_check: true,
93 with_proc_macro: false,
94 prefill_caches: true,
95 };
96
97 let (mut host, vfs, _proc_macro) = {
98 let _it = stdx::timeit("workspace loading");
99 load_workspace_at(&workspace_to_load, &cargo_config, &load_cargo_config, &|_| {}).unwrap()
100 };
101
102 let file_id = {
103 let file = workspace_to_load.join(file);
104 let path = VfsPath::from(AbsPathBuf::assert(file));
9c376795 105 vfs.file_id(&path).unwrap_or_else(|| panic!("can't find virtual file for {path}"))
064997fb
FG
106 };
107
108 {
109 let _it = stdx::timeit("initial");
110 let analysis = host.analysis();
111 analysis.highlight_as_html(file_id, false).unwrap();
112 }
113
114 profile::init_from("*>5");
115 // let _s = profile::heartbeat_span();
116
117 let completion_offset = {
118 let _it = stdx::timeit("change");
119 let mut text = host.analysis().file_text(file_id).unwrap().to_string();
120 let completion_offset =
121 patch(&mut text, "db.struct_data(self.id)", "sel;\ndb.struct_data(self.id)")
122 + "sel".len();
123 let mut change = Change::new();
124 change.change_file(file_id, Some(Arc::new(text)));
125 host.apply_change(change);
126 completion_offset
127 };
128
129 {
130 let _p = profile::span("unqualified path completion");
131 let _span = profile::cpu_span();
132 let analysis = host.analysis();
133 let config = CompletionConfig {
134 enable_postfix_completions: true,
135 enable_imports_on_the_fly: true,
136 enable_self_on_the_fly: true,
137 enable_private_editable: true,
138 callable: Some(CallableSnippets::FillArguments),
139 snippet_cap: SnippetCap::new(true),
140 insert_use: InsertUseConfig {
141 granularity: ImportGranularity::Crate,
142 prefix_kind: hir::PrefixKind::ByCrate,
143 enforce_granularity: true,
144 group: true,
145 skip_glob_imports: true,
146 },
147 snippets: Vec::new(),
2b03887a 148 prefer_no_std: false,
064997fb
FG
149 };
150 let position =
151 FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() };
152 analysis.completions(&config, position, None).unwrap();
153 }
154
155 let completion_offset = {
156 let _it = stdx::timeit("change");
157 let mut text = host.analysis().file_text(file_id).unwrap().to_string();
158 let completion_offset =
159 patch(&mut text, "sel;\ndb.struct_data(self.id)", "self.;\ndb.struct_data(self.id)")
160 + "self.".len();
161 let mut change = Change::new();
162 change.change_file(file_id, Some(Arc::new(text)));
163 host.apply_change(change);
164 completion_offset
165 };
166
167 {
168 let _p = profile::span("dot completion");
169 let _span = profile::cpu_span();
170 let analysis = host.analysis();
171 let config = CompletionConfig {
172 enable_postfix_completions: true,
173 enable_imports_on_the_fly: true,
174 enable_self_on_the_fly: true,
175 enable_private_editable: true,
176 callable: Some(CallableSnippets::FillArguments),
177 snippet_cap: SnippetCap::new(true),
178 insert_use: InsertUseConfig {
179 granularity: ImportGranularity::Crate,
180 prefix_kind: hir::PrefixKind::ByCrate,
181 enforce_granularity: true,
182 group: true,
183 skip_glob_imports: true,
184 },
185 snippets: Vec::new(),
2b03887a 186 prefer_no_std: false,
064997fb
FG
187 };
188 let position =
189 FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() };
190 analysis.completions(&config, position, None).unwrap();
191 }
192}
193
194fn patch(what: &mut String, from: &str, to: &str) -> usize {
195 let idx = what.find(from).unwrap();
196 *what = what.replacen(from, to, 1);
197 idx
198}