//! Open-time measurement on a real vault (run on demand, release build): //! `cargo test --release -p notescraft-engine --test perf_open_cache -- --ignored --nocapture`. //! //! Skipped when `~/Documents/vaults/mdn-docs` is missing. Prints per-stage totals of what //! `Session::index_note` does, then the whole open (cold, then from the index cache). use std::path::PathBuf; use std::time::{Duration, Instant}; use notescraft_engine::Session; fn timed(label: &str, work: impl FnOnce() -> T) -> T { let start = Instant::now(); let out = work(); println!("{label:<34} {:>10.2?}", start.elapsed()); out } fn open_all(root: &std::path::Path) -> Session { let mut session = Session::open_lazy(root).expect("lazy"); while !session.index_step(Duration::MAX).finished {} session } #[test] #[ignore = "measurement, run on demand in a release build"] fn cold_and_cached_open_of_a_real_vault() { let Some(home) = std::env::var_os("HOME") else { return }; let root = PathBuf::from(home).join("Documents/vaults/mdn-docs"); if !root.is_dir() { return; } let listing = notescraft_vault::Vault::open_read_only(&root).and_then(|v| v.list()).expect("list"); let paths: Vec = listing.into_iter().filter(|e| !e.is_dir && e.path.to_ascii_lowercase().ends_with(".md")).map(|e| e.path).collect(); println!("--- {} notes", paths.len()); let texts = timed("read every note", || paths.iter().filter_map(|p| std::fs::read_to_string(root.join(p)).ok()).collect::>()); let mut links = notescraft_index::Index::new(); timed("link index: update_note", || paths.iter().zip(&texts).for_each(|(p, t)| drop(links.update_note(p, t)))); let mut search = notescraft_index::search::SearchIndex::new(); timed("search index: update", || paths.iter().zip(&texts).for_each(|(p, t)| drop(search.update(p, t)))); let mut passages = notescraft_knowledge::Index::default(); timed("knowledge passages: update", || paths.iter().zip(&texts).for_each(|(p, t)| drop(passages.update(p, t)))); let mut vocab = notescraft_knowledge::Vocab::default(); timed("knowledge vocabulary: update", || paths.iter().zip(&texts).for_each(|(p, t)| drop(vocab.update(p, t)))); drop((links, search, passages, vocab, texts)); let _ = std::fs::remove_dir_all(root.join(".notescraft/cache")); let _ = std::fs::remove_file(root.join(".notescraft/knowledge-vocab.json")); let lazy = timed("open_lazy (names only)", || Session::open_lazy(&root).expect("lazy")); drop(lazy); let cold = timed("cold open + index everything", || open_all(&root)); drop(cold); let size = std::fs::metadata(root.join(".notescraft/cache/index-v1.bin")).map_or(0, |meta| meta.len()); println!("cache file: {} MiB", size / (1024 * 1024)); let lazy = timed("open_lazy with a cache", || Session::open_lazy(&root).expect("lazy")); drop(lazy); let cached = timed("cached open + index everything", || open_all(&root)); drop(cached); }