use std::sync::atomic::Ordering::Relaxed;
use super::alloc::{COUNT, LIVE, mb};
pub fn run(path: &str, runs: usize) -> Result<(), String> {
let bytes = std::fs::read(path).map_err(|e| format!("{path}: {e}"))?;
let fonts = twip::font::Fonts::system();
let t = std::time::Instant::now();
let doc = twip::docx::read(&bytes).map_err(|e| format!("{path}: {e:?}"))?;
println!("read {:.1} ms", t.elapsed().as_secs_f64() * 1e3);
let report = |label: &str, t: std::time::Instant, pages: usize, allocs: usize| {
println!("{label}: {:.1} ms, {pages} pages, {allocs} allocations", t.elapsed().as_secs_f64() * 1e3);
for (name, ms, n) in twip::prof::take() {
println!(" {name:<10} {ms:8.1} ms {n:8} calls");
}
};
for k in 0..runs {
let c = COUNT.load(Relaxed);
let t = std::time::Instant::now();
let s = twip::layout::layout(&doc, &fonts);
report(&format!("layout #{k}"), t, s.pages().len(), COUNT.load(Relaxed) - c);
}
let mut cache = twip::layout::cache::LayoutCache::new();
let c = COUNT.load(Relaxed);
let t = std::time::Instant::now();
let s = twip::layout::layout_with(&doc, &fonts, &mut cache);
report("cached cold", t, s.pages().len(), COUNT.load(Relaxed) - c);
drop(s);
let c = COUNT.load(Relaxed);
let t = std::time::Instant::now();
let s = twip::layout::layout_with(&doc, &fonts, &mut cache);
report("cached warm", t, s.pages().len(), COUNT.load(Relaxed) - c);
let (hits, misses) = cache.counts();
println!("cache hits {hits}, misses {misses}");
drop(s);
let base = LIVE.load(Relaxed);
let mut cache = twip::layout::cache::LayoutCache::new();
let s = twip::layout::layout_with(&doc, &fonts, &mut cache);
let both = LIVE.load(Relaxed).saturating_sub(base);
drop(cache);
let snapshot = LIVE.load(Relaxed).saturating_sub(base);
println!("live: cache + snapshot {:.1} MB, snapshot alone {:.1} MB ({} pages)", mb(both), mb(snapshot), s.pages().len());
Ok(())
}