print memory usage for queries

This commit is contained in:
Aleksey Kladov 2019-06-30 14:40:01 +03:00
parent 2ad8220f58
commit d70520eb38
7 changed files with 101 additions and 13 deletions

View file

@ -20,3 +20,4 @@ ra_db = { path = "../ra_db" }
[dependencies.ra_prof]
path = "../ra_prof"
# features = [ "cpuprofiler" ]
# features = [ "jemalloc" ]

View file

@ -6,9 +6,9 @@ use ra_syntax::AstNode;
use crate::Result;
pub fn run(verbose: bool, path: &Path, only: Option<&str>) -> Result<()> {
pub fn run(verbose: bool, memory_usage: bool, path: &Path, only: Option<&str>) -> Result<()> {
let db_load_time = Instant::now();
let (host, roots) = ra_batch::load_cargo(path)?;
let (mut host, roots) = ra_batch::load_cargo(path)?;
let db = host.raw_database();
println!("Database loaded, {} roots, {:?}", roots.len(), db_load_time.elapsed());
let analysis_time = Instant::now();
@ -113,5 +113,12 @@ pub fn run(verbose: bool, path: &Path, only: Option<&str>) -> Result<()> {
(num_exprs_partially_unknown * 100 / num_exprs)
);
println!("Analysis: {:?}, {}", analysis_time.elapsed(), ra_prof::memory_usage());
if memory_usage {
for (name, bytes) in host.per_query_memory_usage() {
println!("{:>8} {}", bytes, name)
}
}
Ok(())
}

View file

@ -24,6 +24,7 @@ fn main() -> Result<()> {
.subcommand(
SubCommand::with_name("analysis-stats")
.arg(Arg::with_name("verbose").short("v").long("verbose"))
.arg(Arg::with_name("memory-usage").long("memory-usage"))
.arg(Arg::with_name("only").short("o").takes_value(true))
.arg(Arg::with_name("path")),
)
@ -71,9 +72,10 @@ fn main() -> Result<()> {
}
("analysis-stats", Some(matches)) => {
let verbose = matches.is_present("verbose");
let memory_usage = matches.is_present("memory-usage");
let path = matches.value_of("path").unwrap_or("");
let only = matches.value_of("only");
analysis_stats::run(verbose, path.as_ref(), only)?;
analysis_stats::run(verbose, memory_usage, path.as_ref(), only)?;
}
("analysis-bench", Some(matches)) => {
let verbose = matches.is_present("verbose");

View file

@ -57,17 +57,21 @@ pub trait InternDatabase: SourceDatabase {
pub trait AstDatabase: InternDatabase {
#[salsa::invoke(crate::source_id::AstIdMap::ast_id_map_query)]
fn ast_id_map(&self, file_id: HirFileId) -> Arc<AstIdMap>;
#[salsa::transparent]
#[salsa::invoke(crate::source_id::AstIdMap::file_item_query)]
fn ast_id_to_node(&self, file_id: HirFileId, ast_id: ErasedFileAstId) -> TreeArc<SyntaxNode>;
#[salsa::transparent]
#[salsa::invoke(crate::ids::HirFileId::parse_or_expand_query)]
fn parse_or_expand(&self, file_id: HirFileId) -> Option<TreeArc<SyntaxNode>>;
#[salsa::invoke(crate::ids::HirFileId::parse_macro_query)]
fn parse_macro(&self, macro_file: ids::MacroFile) -> Option<TreeArc<SyntaxNode>>;
#[salsa::invoke(crate::ids::macro_def_query)]
fn macro_def(&self, macro_id: MacroDefId) -> Option<Arc<mbe::MacroRules>>;
#[salsa::invoke(crate::ids::macro_arg_query)]
fn macro_arg(&self, macro_call: ids::MacroCallId) -> Option<Arc<tt::Subtree>>;

View file

@ -9,7 +9,7 @@ use ra_db::{
salsa::{Database, SweepStrategy},
};
use ra_syntax::SourceFile;
use ra_prof::profile;
use ra_prof::{profile, Bytes, memory_usage};
use relative_path::RelativePathBuf;
use rayon::prelude::*;
@ -243,4 +243,65 @@ impl RootDatabase {
self.query(hir::db::InferQuery).sweep(sweep);
self.query(hir::db::BodyHirQuery).sweep(sweep);
}
pub(crate) fn per_query_memory_usage(&mut self) -> Vec<(String, Bytes)> {
let mut acc: Vec<(String, Bytes)> = vec![];
let sweep = SweepStrategy::default().discard_values().sweep_all_revisions();
macro_rules! sweep_each_query {
($($q:path)*) => {$(
let before = memory_usage().allocated;
self.query($q).sweep(sweep);
let after = memory_usage().allocated;
let q: $q = Default::default();
let name = format!("{:?}", q);
acc.push((name, before - after));
)*}
}
sweep_each_query![
ra_db::ParseQuery
ra_db::SourceRootCratesQuery
hir::db::AstIdMapQuery
hir::db::ParseMacroQuery
hir::db::MacroDefQuery
hir::db::MacroArgQuery
hir::db::MacroExpandQuery
hir::db::StructDataQuery
hir::db::EnumDataQuery
hir::db::TraitDataQuery
hir::db::TraitItemsIndexQuery
hir::db::RawItemsQuery
hir::db::RawItemsWithSourceMapQuery
hir::db::CrateDefMapQuery
hir::db::ImplsInModuleQuery
hir::db::ImplsInModuleWithSourceMapQuery
hir::db::GenericParamsQuery
hir::db::FnDataQuery
hir::db::TypeAliasDataQuery
hir::db::ConstDataQuery
hir::db::StaticDataQuery
hir::db::ModuleLangItemsQuery
hir::db::LangItemsQuery
hir::db::LangItemQuery
hir::db::DocumentationQuery
hir::db::ExprScopesQuery
hir::db::InferQuery
hir::db::TypeForDefQuery
hir::db::TypeForFieldQuery
hir::db::CallableItemSignatureQuery
hir::db::GenericPredicatesQuery
hir::db::GenericDefaultsQuery
hir::db::BodyWithSourceMapQuery
hir::db::BodyHirQuery
hir::db::ImplsInCrateQuery
hir::db::ImplsForTraitQuery
hir::db::AssociatedTyDataQuery
hir::db::TraitDatumQuery
hir::db::StructDatumQuery
hir::db::ImplDatumQuery
hir::db::ImplementsQuery
hir::db::NormalizeQuery
];
acc.sort_by_key(|it| std::cmp::Reverse(it.1));
acc
}
}

View file

@ -270,6 +270,10 @@ impl AnalysisHost {
pub fn collect_garbage(&mut self) {
self.db.collect_garbage();
}
/// NB: this clears the database
pub fn per_query_memory_usage(&mut self) -> Vec<(String, ra_prof::Bytes)> {
self.db.per_query_memory_usage()
}
pub fn raw_database(&self) -> &(impl hir::db::HirDatabase + salsa::Database) {
&self.db
}

View file

@ -27,21 +27,23 @@ impl fmt::Display for MemoryUsage {
}
}
#[derive(Default)]
#[derive(Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
pub struct Bytes(usize);
impl fmt::Display for Bytes {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let bytes = self.0;
if bytes < 4096 {
return write!(f, "{} bytes", bytes);
let mut value = bytes;
let mut suffix = "b";
if value > 4096 {
value /= 1024;
suffix = "kb";
if value > 4096 {
value /= 1024;
suffix = "mb";
}
let kb = bytes / 1024;
if kb < 4096 {
return write!(f, "{}kb", kb);
}
let mb = kb / 1024;
write!(f, "{}mb", mb)
f.pad(&format!("{}{}", value, suffix))
}
}
@ -50,3 +52,10 @@ impl std::ops::AddAssign<usize> for Bytes {
self.0 += x;
}
}
impl std::ops::Sub for Bytes {
type Output = Bytes;
fn sub(self, rhs: Bytes) -> Bytes {
Bytes(self.0 - rhs.0)
}
}