]> git.lizzy.rs Git - rust.git/commitdiff
internal: add integrated completion benchmark
authorAleksey Kladov <aleksey.kladov@gmail.com>
Tue, 4 May 2021 11:02:23 +0000 (14:02 +0300)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Tue, 4 May 2021 12:14:33 +0000 (15:14 +0300)
crates/rust-analyzer/src/benchmarks.rs [deleted file]
crates/rust-analyzer/src/integrated_benchmarks.rs [new file with mode: 0644]
crates/rust-analyzer/src/lib.rs

diff --git a/crates/rust-analyzer/src/benchmarks.rs b/crates/rust-analyzer/src/benchmarks.rs
deleted file mode 100644 (file)
index 74bab46..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-//! Fully integrated benchmarks for rust-analyzer, which load real cargo
-//! projects.
-//!
-//! The benchmark here is used to debug specific performance regressions. If you
-//! notice that, eg, completion is slow in some specific case, you can  modify
-//! code here exercise this specific completion, and thus have a fast
-//! edit/compile/test cycle.
-//!
-//! Note that "Rust Analyzer: Run" action does not allow running a single test
-//! in release mode in VS Code. There's however "Rust Analyzer: Copy Run Command Line"
-//! which you can use to paste the command in terminal and add `--release` manually.
-
-use std::sync::Arc;
-
-use ide::Change;
-use test_utils::project_root;
-use vfs::{AbsPathBuf, VfsPath};
-
-use crate::cli::load_cargo::{load_workspace_at, LoadCargoConfig};
-
-#[test]
-fn integrated_highlighting_benchmark() {
-    // Don't run slow benchmark by default
-    if true {
-        return;
-    }
-
-    // Load rust-analyzer itself.
-    let workspace_to_load = project_root();
-    let file = "./crates/ide_db/src/apply_change.rs";
-
-    let cargo_config = Default::default();
-    let load_cargo_config = LoadCargoConfig {
-        load_out_dirs_from_check: true,
-        wrap_rustc: false,
-        with_proc_macro: false,
-    };
-
-    let (mut host, vfs, _proc_macro) = {
-        let _it = stdx::timeit("workspace loading");
-        load_workspace_at(&workspace_to_load, &cargo_config, &load_cargo_config, &|_| {}).unwrap()
-    };
-
-    let file_id = {
-        let file = workspace_to_load.join(file);
-        let path = VfsPath::from(AbsPathBuf::assert(file));
-        vfs.file_id(&path).unwrap_or_else(|| panic!("can't find virtual file for {}", path))
-    };
-
-    {
-        let _it = stdx::timeit("initial");
-        let analysis = host.analysis();
-        analysis.highlight_as_html(file_id, false).unwrap();
-    }
-
-    profile::init_from("*>100");
-    // let _s = profile::heartbeat_span();
-
-    {
-        let _it = stdx::timeit("change");
-        let mut text = host.analysis().file_text(file_id).unwrap().to_string();
-        text.push_str("\npub fn _dummy() {}\n");
-        let mut change = Change::new();
-        change.change_file(file_id, Some(Arc::new(text)));
-        host.apply_change(change);
-    }
-
-    {
-        let _it = stdx::timeit("after change");
-        let _span = profile::cpu_span();
-        let analysis = host.analysis();
-        analysis.highlight_as_html(file_id, false).unwrap();
-    }
-}
diff --git a/crates/rust-analyzer/src/integrated_benchmarks.rs b/crates/rust-analyzer/src/integrated_benchmarks.rs
new file mode 100644 (file)
index 0000000..411446b
--- /dev/null
@@ -0,0 +1,186 @@
+//! Fully integrated benchmarks for rust-analyzer, which load real cargo
+//! projects.
+//!
+//! The benchmark here is used to debug specific performance regressions. If you
+//! notice that, eg, completion is slow in some specific case, you can  modify
+//! code here exercise this specific completion, and thus have a fast
+//! edit/compile/test cycle.
+//!
+//! Note that "Rust Analyzer: Run" action does not allow running a single test
+//! in release mode in VS Code. There's however "Rust Analyzer: Copy Run Command Line"
+//! which you can use to paste the command in terminal and add `--release` manually.
+
+use std::{convert::TryFrom, sync::Arc};
+
+use ide::{Change, CompletionConfig, FilePosition, TextSize};
+use ide_db::helpers::{insert_use::InsertUseConfig, merge_imports::MergeBehavior, SnippetCap};
+use test_utils::project_root;
+use vfs::{AbsPathBuf, VfsPath};
+
+use crate::cli::load_cargo::{load_workspace_at, LoadCargoConfig};
+
+#[test]
+fn integrated_highlighting_benchmark() {
+    // Don't run slow benchmark by default
+    if true {
+        return;
+    }
+
+    // Load rust-analyzer itself.
+    let workspace_to_load = project_root();
+    let file = "./crates/ide_db/src/apply_change.rs";
+
+    let cargo_config = Default::default();
+    let load_cargo_config = LoadCargoConfig {
+        load_out_dirs_from_check: true,
+        wrap_rustc: false,
+        with_proc_macro: false,
+    };
+
+    let (mut host, vfs, _proc_macro) = {
+        let _it = stdx::timeit("workspace loading");
+        load_workspace_at(&workspace_to_load, &cargo_config, &load_cargo_config, &|_| {}).unwrap()
+    };
+
+    let file_id = {
+        let file = workspace_to_load.join(file);
+        let path = VfsPath::from(AbsPathBuf::assert(file));
+        vfs.file_id(&path).unwrap_or_else(|| panic!("can't find virtual file for {}", path))
+    };
+
+    {
+        let _it = stdx::timeit("initial");
+        let analysis = host.analysis();
+        analysis.highlight_as_html(file_id, false).unwrap();
+    }
+
+    profile::init_from("*>100");
+    // let _s = profile::heartbeat_span();
+
+    {
+        let _it = stdx::timeit("change");
+        let mut text = host.analysis().file_text(file_id).unwrap().to_string();
+        text.push_str("\npub fn _dummy() {}\n");
+        let mut change = Change::new();
+        change.change_file(file_id, Some(Arc::new(text)));
+        host.apply_change(change);
+    }
+
+    {
+        let _it = stdx::timeit("after change");
+        let _span = profile::cpu_span();
+        let analysis = host.analysis();
+        analysis.highlight_as_html(file_id, false).unwrap();
+    }
+}
+
+#[test]
+fn integrated_completion_benchmark() {
+    // Don't run slow benchmark by default
+    if true {
+        return;
+    }
+
+    // Load rust-analyzer itself.
+    let workspace_to_load = project_root();
+    let file = "./crates/hir/src/lib.rs";
+
+    let cargo_config = Default::default();
+    let load_cargo_config = LoadCargoConfig {
+        load_out_dirs_from_check: true,
+        wrap_rustc: false,
+        with_proc_macro: false,
+    };
+
+    let (mut host, vfs, _proc_macro) = {
+        let _it = stdx::timeit("workspace loading");
+        load_workspace_at(&workspace_to_load, &cargo_config, &load_cargo_config, &|_| {}).unwrap()
+    };
+
+    let file_id = {
+        let file = workspace_to_load.join(file);
+        let path = VfsPath::from(AbsPathBuf::assert(file));
+        vfs.file_id(&path).unwrap_or_else(|| panic!("can't find virtual file for {}", path))
+    };
+
+    {
+        let _it = stdx::timeit("initial");
+        let analysis = host.analysis();
+        analysis.highlight_as_html(file_id, false).unwrap();
+    }
+
+    profile::init_from("*>5");
+    // let _s = profile::heartbeat_span();
+
+    let completion_offset = {
+        let _it = stdx::timeit("change");
+        let mut text = host.analysis().file_text(file_id).unwrap().to_string();
+        let completion_offset =
+            patch(&mut text, "db.struct_data(self.id)", "sel;\ndb.struct_data(self.id)")
+                + "sel".len();
+        let mut change = Change::new();
+        change.change_file(file_id, Some(Arc::new(text)));
+        host.apply_change(change);
+        completion_offset
+    };
+
+    {
+        let _it = stdx::timeit("unqualified path completion");
+        let _span = profile::cpu_span();
+        let analysis = host.analysis();
+        let config = CompletionConfig {
+            enable_postfix_completions: true,
+            enable_imports_on_the_fly: true,
+            add_call_parenthesis: true,
+            add_call_argument_snippets: true,
+            snippet_cap: SnippetCap::new(true),
+            insert_use: InsertUseConfig {
+                merge: Some(MergeBehavior::Full),
+                prefix_kind: hir::PrefixKind::ByCrate,
+                group: true,
+            },
+        };
+        let position =
+            FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() };
+        analysis.completions(&config, position).unwrap();
+    }
+
+    let completion_offset = {
+        let _it = stdx::timeit("change");
+        let mut text = host.analysis().file_text(file_id).unwrap().to_string();
+        let completion_offset =
+            patch(&mut text, "sel;\ndb.struct_data(self.id)", "self.;\ndb.struct_data(self.id)")
+                + "self.".len();
+        let mut change = Change::new();
+        change.change_file(file_id, Some(Arc::new(text)));
+        host.apply_change(change);
+        completion_offset
+    };
+
+    {
+        let _it = stdx::timeit("dot completion");
+        let _span = profile::cpu_span();
+        let analysis = host.analysis();
+        let config = CompletionConfig {
+            enable_postfix_completions: true,
+            enable_imports_on_the_fly: true,
+            add_call_parenthesis: true,
+            add_call_argument_snippets: true,
+            snippet_cap: SnippetCap::new(true),
+            insert_use: InsertUseConfig {
+                merge: Some(MergeBehavior::Full),
+                prefix_kind: hir::PrefixKind::ByCrate,
+                group: true,
+            },
+        };
+        let position =
+            FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() };
+        analysis.completions(&config, position).unwrap();
+    }
+}
+
+fn patch(what: &mut String, from: &str, to: &str) -> usize {
+    let idx = what.find(from).unwrap();
+    *what = what.replacen(from, to, 1);
+    idx
+}
index d9a5030a0fd46ae94841a3587ec3e197b0ab1d75..da7e24becd0ac4674ffb99fb63ed128e468c9e91 100644 (file)
@@ -40,7 +40,7 @@ macro_rules! eprintln {
 pub mod config;
 
 #[cfg(test)]
-mod benchmarks;
+mod integrated_benchmarks;
 
 use serde::de::DeserializeOwned;
 use std::fmt;