about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/base-db/src/lib.rs2
-rw-r--r--crates/rust-analyzer/src/integrated_benchmarks.rs80
-rw-r--r--crates/rust-analyzer/src/tracing/config.rs39
-rw-r--r--crates/rust-analyzer/src/tracing/hprof.rs19
4 files changed, 94 insertions, 46 deletions
diff --git a/crates/base-db/src/lib.rs b/crates/base-db/src/lib.rs
index cb2e6cdaa28..758d2a45c8f 100644
--- a/crates/base-db/src/lib.rs
+++ b/crates/base-db/src/lib.rs
@@ -43,7 +43,7 @@ pub trait Upcast<T: ?Sized> {
 }
 
 pub const DEFAULT_PARSE_LRU_CAP: usize = 128;
-pub const DEFAULT_BORROWCK_LRU_CAP: usize = 256;
+pub const DEFAULT_BORROWCK_LRU_CAP: usize = 1024;
 
 pub trait FileLoader {
     /// Text of the file.
diff --git a/crates/rust-analyzer/src/integrated_benchmarks.rs b/crates/rust-analyzer/src/integrated_benchmarks.rs
index 28eae6079c5..3bba4847f92 100644
--- a/crates/rust-analyzer/src/integrated_benchmarks.rs
+++ b/crates/rust-analyzer/src/integrated_benchmarks.rs
@@ -11,7 +11,9 @@
 //! which you can use to paste the command in terminal and add `--release` manually.
 
 use hir::ChangeWithProcMacros;
-use ide::{AnalysisHost, CallableSnippets, CompletionConfig, FilePosition, TextSize};
+use ide::{
+    AnalysisHost, CallableSnippets, CompletionConfig, DiagnosticsConfig, FilePosition, TextSize,
+};
 use ide_db::{
     imports::insert_use::{ImportGranularity, InsertUseConfig},
     SnippetCap,
@@ -157,7 +159,7 @@ fn integrated_completion_benchmark() {
         analysis.completions(&config, position, None).unwrap();
     }
 
-    crate::tracing::hprof::init("*>5");
+    let _g = crate::tracing::hprof::init("*");
 
     let completion_offset = {
         let _it = stdx::timeit("change");
@@ -244,6 +246,80 @@ fn integrated_completion_benchmark() {
     }
 }
 
+#[test]
+fn integrated_diagnostics_benchmark() {
+    if std::env::var("RUN_SLOW_BENCHES").is_err() {
+        return;
+    }
+
+    // Load rust-analyzer itself.
+    let workspace_to_load = project_root();
+    let file = "./crates/hir/src/lib.rs";
+
+    let cargo_config = CargoConfig {
+        sysroot: Some(project_model::RustLibSource::Discover),
+        ..CargoConfig::default()
+    };
+    let load_cargo_config = LoadCargoConfig {
+        load_out_dirs_from_check: true,
+        with_proc_macro_server: ProcMacroServerChoice::None,
+        prefill_caches: true,
+    };
+
+    let (db, vfs, _proc_macro) = {
+        let _it = stdx::timeit("workspace loading");
+        load_workspace_at(&workspace_to_load, &cargo_config, &load_cargo_config, &|_| {}).unwrap()
+    };
+    let mut host = AnalysisHost::with_database(db);
+
+    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 diagnostics_config = DiagnosticsConfig {
+        enabled: false,
+        proc_macros_enabled: true,
+        proc_attr_macros_enabled: true,
+        disable_experimental: true,
+        disabled: Default::default(),
+        expr_fill_default: Default::default(),
+        style_lints: false,
+        insert_use: InsertUseConfig {
+            granularity: ImportGranularity::Crate,
+            enforce_granularity: false,
+            prefix_kind: hir::PrefixKind::ByCrate,
+            group: true,
+            skip_glob_imports: true,
+        },
+        prefer_no_std: false,
+        prefer_prelude: false,
+    };
+    host.analysis()
+        .diagnostics(&diagnostics_config, ide::AssistResolveStrategy::None, file_id)
+        .unwrap();
+
+    let _g = crate::tracing::hprof::init("*>1");
+
+    {
+        let _it = stdx::timeit("change");
+        let mut text = host.analysis().file_text(file_id).unwrap().to_string();
+        patch(&mut text, "db.struct_data(self.id)", "();\ndb.struct_data(self.id)");
+        let mut change = ChangeWithProcMacros::new();
+        change.change_file(file_id, Some(Arc::from(text)));
+        host.apply_change(change);
+    };
+
+    {
+        let _p = tracing::span!(tracing::Level::INFO, "diagnostics").entered();
+        let _span = profile::cpu_span();
+        host.analysis()
+            .diagnostics(&diagnostics_config, ide::AssistResolveStrategy::None, file_id)
+            .unwrap();
+    }
+}
+
 fn patch(what: &mut String, from: &str, to: &str) -> usize {
     let idx = what.find(from).unwrap();
     *what = what.replacen(from, to, 1);
diff --git a/crates/rust-analyzer/src/tracing/config.rs b/crates/rust-analyzer/src/tracing/config.rs
index fcdbd1e6d9b..2bc389a0517 100644
--- a/crates/rust-analyzer/src/tracing/config.rs
+++ b/crates/rust-analyzer/src/tracing/config.rs
@@ -6,11 +6,8 @@ use std::io;
 use anyhow::Context;
 use tracing::{level_filters::LevelFilter, Level};
 use tracing_subscriber::{
-    filter::{self, Targets},
-    fmt::{format::FmtSpan, MakeWriter},
-    layer::SubscriberExt,
-    util::SubscriberInitExt,
-    Layer, Registry,
+    filter::Targets, fmt::MakeWriter, layer::SubscriberExt, util::SubscriberInitExt, Layer,
+    Registry,
 };
 use tracing_tree::HierarchicalLayer;
 
@@ -50,10 +47,7 @@ where
 
         let writer = self.writer;
 
-        let ra_fmt_layer = tracing_subscriber::fmt::layer()
-            .with_span_events(FmtSpan::CLOSE)
-            .with_writer(writer)
-            .with_filter(filter);
+        let ra_fmt_layer = tracing_subscriber::fmt::layer().with_writer(writer).with_filter(filter);
 
         let mut chalk_layer = None;
         if let Some(chalk_filter) = self.chalk_filter {
@@ -74,32 +68,7 @@ where
             );
         };
 
-        let mut profiler_layer = None;
-        if let Some(spec) = self.profile_filter {
-            let (write_filter, allowed_names) = hprof::WriteFilter::from_spec(&spec);
-
-            // this filter the first pass for `tracing`: these are all the "profiling" spans, but things like
-            // span depth or duration are not filtered here: that only occurs at write time.
-            let profile_filter = filter::filter_fn(move |metadata| {
-                let allowed = match &allowed_names {
-                    Some(names) => names.contains(metadata.name()),
-                    None => true,
-                };
-
-                metadata.is_span()
-                    && allowed
-                    && metadata.level() >= &Level::INFO
-                    && !metadata.target().starts_with("salsa")
-                    && !metadata.target().starts_with("chalk")
-            });
-
-            let layer = hprof::SpanTree::default()
-                .aggregate(true)
-                .spec_filter(write_filter)
-                .with_filter(profile_filter);
-
-            profiler_layer = Some(layer);
-        }
+        let profiler_layer = self.profile_filter.map(|spec| hprof::layer(&spec));
 
         Registry::default().with(ra_fmt_layer).with(chalk_layer).with(profiler_layer).try_init()?;
 
diff --git a/crates/rust-analyzer/src/tracing/hprof.rs b/crates/rust-analyzer/src/tracing/hprof.rs
index 5fcda6ba136..af1a74a9350 100644
--- a/crates/rust-analyzer/src/tracing/hprof.rs
+++ b/crates/rust-analyzer/src/tracing/hprof.rs
@@ -53,6 +53,14 @@ use tracing_subscriber::{
 use crate::tracing::hprof;
 
 pub fn init(spec: &str) -> tracing::subscriber::DefaultGuard {
+    let subscriber = Registry::default().with(layer(spec));
+    tracing::subscriber::set_default(subscriber)
+}
+
+pub fn layer<S>(spec: &str) -> impl Layer<S>
+where
+    S: Subscriber + for<'span> tracing_subscriber::registry::LookupSpan<'span>,
+{
     let (write_filter, allowed_names) = WriteFilter::from_spec(spec);
 
     // this filter the first pass for `tracing`: these are all the "profiling" spans, but things like
@@ -66,17 +74,12 @@ pub fn init(spec: &str) -> tracing::subscriber::DefaultGuard {
         metadata.is_span()
             && allowed
             && metadata.level() >= &Level::INFO
-            && !metadata.target().starts_with("salsa")
+            // && !metadata.target().starts_with("salsa")
+            && !metadata.target().contains("compute_exhaustiveness_and_usefulness")
             && !metadata.target().starts_with("chalk")
     });
 
-    let layer = hprof::SpanTree::default()
-        .aggregate(true)
-        .spec_filter(write_filter)
-        .with_filter(profile_filter);
-
-    let subscriber = Registry::default().with(layer);
-    tracing::subscriber::set_default(subscriber)
+    hprof::SpanTree::default().aggregate(true).spec_filter(write_filter).with_filter(profile_filter)
 }
 
 #[derive(Default, Debug)]