rust_analyzer/cli/
prime_caches.rs

1//! Load the project and run cache priming.
2//!
3//! Unlike `analysis-stats`, this command is intended to be used for
4//! benchmarking rust-analyzer's default startup configuration. It *does not*
5//! attempt to simulate the full IDE experience through the lifetime of the
6//! an editing session.
7
8use load_cargo::{LoadCargoConfig, ProcMacroServerChoice, load_workspace};
9use profile::StopWatch;
10use project_model::{ProjectManifest, ProjectWorkspace};
11use vfs::AbsPathBuf;
12
13use crate::cli::flags;
14
15impl flags::PrimeCaches {
16    pub fn run(self) -> anyhow::Result<()> {
17        let root =
18            vfs::AbsPathBuf::assert_utf8(std::env::current_dir()?.join(&self.path)).normalize();
19        let config = crate::config::Config::new(
20            root.clone(),
21            lsp_types::ClientCapabilities::default(),
22            vec![],
23            None,
24        );
25        let mut stop_watch = StopWatch::start();
26
27        let cargo_config = config.cargo(None);
28        let with_proc_macro_server = if let Some(p) = &self.proc_macro_srv {
29            let path = vfs::AbsPathBuf::assert_utf8(std::env::current_dir()?.join(p));
30            ProcMacroServerChoice::Explicit(path)
31        } else {
32            ProcMacroServerChoice::Sysroot
33        };
34        let load_cargo_config = LoadCargoConfig {
35            load_out_dirs_from_check: !self.disable_build_scripts,
36            with_proc_macro_server,
37            // while this command is nominally focused on cache priming,
38            // we want to ensure that this command, not `load_workspace_at`,
39            // is responsible for that work.
40            prefill_caches: false,
41        };
42
43        let root = AbsPathBuf::assert_utf8(std::env::current_dir()?.join(root));
44        let root = ProjectManifest::discover_single(&root)?;
45        let workspace = ProjectWorkspace::load(root, &cargo_config, &|_| {})?;
46
47        let (db, _, _) = load_workspace(workspace, &cargo_config.extra_env, &load_cargo_config)?;
48        let elapsed = stop_watch.elapsed();
49        eprintln!(
50            "Load time: {:?}ms, memory allocated: {}MB",
51            elapsed.time.as_millis(),
52            elapsed.memory.allocated.megabytes() as u64
53        );
54
55        let threads = self.num_threads.unwrap_or_else(num_cpus::get_physical);
56        ide_db::prime_caches::parallel_prime_caches(&db, threads, &|_| ());
57
58        let elapsed = stop_watch.elapsed();
59        eprintln!(
60            "Cache priming time: {:?}ms, total memory allocated: {}MB",
61            elapsed.time.as_millis(),
62            elapsed.memory.allocated.megabytes() as u64
63        );
64
65        Ok(())
66    }
67}