mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-15 01:17:27 +00:00
Add diagnostics integrated benchmark
This commit is contained in:
parent
a3b6e891ea
commit
09d33f3e1e
4 changed files with 94 additions and 46 deletions
|
@ -43,7 +43,7 @@ pub trait Upcast<T: ?Sized> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const DEFAULT_PARSE_LRU_CAP: usize = 128;
|
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 {
|
pub trait FileLoader {
|
||||||
/// Text of the file.
|
/// Text of the file.
|
||||||
|
|
|
@ -11,7 +11,9 @@
|
||||||
//! which you can use to paste the command in terminal and add `--release` manually.
|
//! which you can use to paste the command in terminal and add `--release` manually.
|
||||||
|
|
||||||
use hir::ChangeWithProcMacros;
|
use hir::ChangeWithProcMacros;
|
||||||
use ide::{AnalysisHost, CallableSnippets, CompletionConfig, FilePosition, TextSize};
|
use ide::{
|
||||||
|
AnalysisHost, CallableSnippets, CompletionConfig, DiagnosticsConfig, FilePosition, TextSize,
|
||||||
|
};
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
imports::insert_use::{ImportGranularity, InsertUseConfig},
|
imports::insert_use::{ImportGranularity, InsertUseConfig},
|
||||||
SnippetCap,
|
SnippetCap,
|
||||||
|
@ -157,7 +159,7 @@ fn integrated_completion_benchmark() {
|
||||||
analysis.completions(&config, position, None).unwrap();
|
analysis.completions(&config, position, None).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::tracing::hprof::init("*>5");
|
let _g = crate::tracing::hprof::init("*");
|
||||||
|
|
||||||
let completion_offset = {
|
let completion_offset = {
|
||||||
let _it = stdx::timeit("change");
|
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 {
|
fn patch(what: &mut String, from: &str, to: &str) -> usize {
|
||||||
let idx = what.find(from).unwrap();
|
let idx = what.find(from).unwrap();
|
||||||
*what = what.replacen(from, to, 1);
|
*what = what.replacen(from, to, 1);
|
||||||
|
|
|
@ -6,11 +6,8 @@ use std::io;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use tracing::{level_filters::LevelFilter, Level};
|
use tracing::{level_filters::LevelFilter, Level};
|
||||||
use tracing_subscriber::{
|
use tracing_subscriber::{
|
||||||
filter::{self, Targets},
|
filter::Targets, fmt::MakeWriter, layer::SubscriberExt, util::SubscriberInitExt, Layer,
|
||||||
fmt::{format::FmtSpan, MakeWriter},
|
Registry,
|
||||||
layer::SubscriberExt,
|
|
||||||
util::SubscriberInitExt,
|
|
||||||
Layer, Registry,
|
|
||||||
};
|
};
|
||||||
use tracing_tree::HierarchicalLayer;
|
use tracing_tree::HierarchicalLayer;
|
||||||
|
|
||||||
|
@ -50,10 +47,7 @@ where
|
||||||
|
|
||||||
let writer = self.writer;
|
let writer = self.writer;
|
||||||
|
|
||||||
let ra_fmt_layer = tracing_subscriber::fmt::layer()
|
let ra_fmt_layer = tracing_subscriber::fmt::layer().with_writer(writer).with_filter(filter);
|
||||||
.with_span_events(FmtSpan::CLOSE)
|
|
||||||
.with_writer(writer)
|
|
||||||
.with_filter(filter);
|
|
||||||
|
|
||||||
let mut chalk_layer = None;
|
let mut chalk_layer = None;
|
||||||
if let Some(chalk_filter) = self.chalk_filter {
|
if let Some(chalk_filter) = self.chalk_filter {
|
||||||
|
@ -74,32 +68,7 @@ where
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut profiler_layer = None;
|
let profiler_layer = self.profile_filter.map(|spec| hprof::layer(&spec));
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
Registry::default().with(ra_fmt_layer).with(chalk_layer).with(profiler_layer).try_init()?;
|
Registry::default().with(ra_fmt_layer).with(chalk_layer).with(profiler_layer).try_init()?;
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,14 @@ use tracing_subscriber::{
|
||||||
use crate::tracing::hprof;
|
use crate::tracing::hprof;
|
||||||
|
|
||||||
pub fn init(spec: &str) -> tracing::subscriber::DefaultGuard {
|
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);
|
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
|
// 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()
|
metadata.is_span()
|
||||||
&& allowed
|
&& allowed
|
||||||
&& metadata.level() >= &Level::INFO
|
&& 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")
|
&& !metadata.target().starts_with("chalk")
|
||||||
});
|
});
|
||||||
|
|
||||||
let layer = hprof::SpanTree::default()
|
hprof::SpanTree::default().aggregate(true).spec_filter(write_filter).with_filter(profile_filter)
|
||||||
.aggregate(true)
|
|
||||||
.spec_filter(write_filter)
|
|
||||||
.with_filter(profile_filter);
|
|
||||||
|
|
||||||
let subscriber = Registry::default().with(layer);
|
|
||||||
tracing::subscriber::set_default(subscriber)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
|
|
Loading…
Reference in a new issue