From 09d33f3e1e295927fee92f92a6497eb76d1b767c Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 7 Mar 2024 09:33:48 +0100 Subject: [PATCH] Add diagnostics integrated benchmark --- crates/base-db/src/lib.rs | 2 +- .../src/integrated_benchmarks.rs | 80 ++++++++++++++++++- crates/rust-analyzer/src/tracing/config.rs | 39 +-------- crates/rust-analyzer/src/tracing/hprof.rs | 19 +++-- 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 { } 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(spec: &str) -> impl Layer +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)]