source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6"
+[[package]]
+name = "countme"
+version = "2.0.0-pre.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c5716604cba7c02a846ecad3f4a3fd2d2b641faccc2a24a51efb21aff0d01f35"
+dependencies = [
+ "dashmap",
+ "once_cell",
+ "rustc-hash",
+]
+
[[package]]
name = "crc32fast"
version = "1.2.1"
"lazy_static",
]
+[[package]]
+name = "dashmap"
+version = "4.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c"
+dependencies = [
+ "cfg-if 1.0.0",
+ "num_cpus",
+]
+
[[package]]
name = "dissimilar"
version = "1.0.2"
version = "0.0.0"
dependencies = [
"cfg-if 1.0.0",
+ "countme",
"jemalloc-ctl",
"la-arena",
"libc",
[[package]]
name = "rowan"
-version = "0.12.0"
+version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bea4527c692099becd37ec777cfd6949d0534348528d2fc84ee420d2d5fac83d"
+checksum = "24c2d78254049413f9d73495f883e7fa0b7a7d4b88468cd72a3bbbd0ad585cd1"
dependencies = [
+ "countme",
"hashbrown",
"memoffset",
"rustc-hash",
HirFileId, InFile,
};
use la_arena::{Arena, Idx, RawIdx};
+use profile::Count;
use rustc_hash::FxHashMap;
use smallvec::SmallVec;
use syntax::{ast, match_ast};
/// The item tree of a source file.
#[derive(Debug, Eq, PartialEq)]
pub struct ItemTree {
+ _c: Count<Self>,
+
top_level: SmallVec<[ModItem; 1]>,
attrs: FxHashMap<AttrOwner, RawAttrs>,
}
fn empty() -> Self {
- Self { top_level: Default::default(), attrs: Default::default(), data: Default::default() }
+ Self {
+ _c: Count::new(),
+ top_level: Default::default(),
+ attrs: Default::default(),
+ data: Default::default(),
+ }
}
fn shrink_to_fit(&mut self) {
use base_db::{CrateId, Edition, FileId};
use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile};
use la_arena::Arena;
+use profile::Count;
use rustc_hash::FxHashMap;
use stdx::format_to;
use syntax::{ast, AstNode};
/// Contains all top-level defs from a macro-expanded crate
#[derive(Debug, PartialEq, Eq)]
pub struct DefMap {
+ _c: Count<Self>,
parent: Option<Arc<DefMap>>,
root: LocalModuleId,
modules: Arena<ModuleData>,
let mut modules: Arena<ModuleData> = Arena::default();
let root = modules.alloc(ModuleData::default());
DefMap {
+ _c: Count::new(),
parent: None,
krate,
edition,
format_to!(buf, "{}\n", syntax_tree_stats(db));
format_to!(buf, "{} (macros)\n", macro_syntax_tree_stats(db));
format_to!(buf, "{} total\n", memory_usage());
+ format_to!(buf, "\ncounts:\n{}", profile::countme::get_all());
if let Some(file_id) = file_id {
format_to!(buf, "\nfile info:\n");
None => format_to!(buf, "does not belong to any crate"),
}
}
+
buf
}
cfg-if = "1"
libc = "0.2.73"
la-arena = { version = "0.2.0", path = "../../lib/arena" }
+countme = { version = "2.0.0-pre.2", features = ["enable"] }
jemalloc-ctl = { version = "0.3.3", optional = true }
[target.'cfg(target_os = "linux")'.dependencies]
use std::{
cell::RefCell,
collections::{BTreeMap, HashSet},
+ env,
io::{stderr, Write},
sync::{
atomic::{AtomicBool, Ordering},
/// env RA_PROFILE=foo|bar|baz // enabled only selected entries
/// env RA_PROFILE=*@3>10 // dump everything, up to depth 3, if it takes more than 10 ms
pub fn init() {
- let spec = std::env::var("RA_PROFILE").unwrap_or_default();
+ countme::enable(env::var("RA_COUNT").is_ok());
+ let spec = env::var("RA_PROFILE").unwrap_or_default();
init_from(&spec);
}
stop_watch::{StopWatch, StopWatchSpan},
};
+pub use countme;
+/// Include `_c: Count<Self>` field in important structs to count them.
+///
+/// To view the counts, run with `RA_COUNT=1`. The overhead of disabled count is
+/// almost zero.
+pub use countme::Count;
+
thread_local!(static IN_SCOPE: RefCell<bool> = RefCell::new(false));
/// Allows to check if the current code is withing some dynamic scope, can be
//! errors.
use std::{
+ env,
path::PathBuf,
time::{SystemTime, UNIX_EPOCH},
};
report_metric("total memory", memory.allocated.megabytes() as u64, "MB");
}
+ if env::var("RA_COUNT").is_ok() {
+ eprintln!("{}", profile::countme::get_all());
+ }
+
if self.memory_usage && verbosity.is_verbose() {
print_memory_usage(host, vfs);
}
In particular, I have `export RA_PROFILE='*>10'` in my shell profile.
+We also have a "counting" profiler which counts number of instances of popular structs.
+It is enabled by `RA_COUNT=1`.
+
To measure time for from-scratch analysis, use something like this:
```