| 1 | //! Measures the launcher-side cost of starting a game: the part we control. |
| 2 | use std::time::Instant; |
| 3 | |
| 4 | fn main() { |
| 5 | let root = dirs_root(); |
| 6 | println!("root: {}", root.display()); |
| 7 | |
| 8 | // What "instant launch" skips: the round trip to Roblox before playing. |
| 9 | let mut samples = Vec::new(); |
| 10 | for _ in 0..5 { |
| 11 | let t = Instant::now(); |
| 12 | let _ = nox_roblox::deploy::latest(nox_roblox::Binary::Player, "LIVE"); |
| 13 | samples.push(t.elapsed().as_secs_f64() * 1000.0); |
| 14 | } |
| 15 | samples.sort_by(|a, b| a.partial_cmp(b).unwrap()); |
| 16 | println!( |
| 17 | "update check (skipped by instant launch): min {:.0} ms, median {:.0} ms, max {:.0} ms", |
| 18 | samples[0], |
| 19 | samples[samples.len() / 2], |
| 20 | samples[samples.len() - 1] |
| 21 | ); |
| 22 | |
| 23 | // What the instant path still has to do before exec. |
| 24 | let t = Instant::now(); |
| 25 | let installed = nox_roblox::deploy::installed_versions(&root); |
| 26 | let scan = t.elapsed().as_secs_f64() * 1000.0; |
| 27 | println!("version scan: {scan:.2} ms ({} installed)", installed.len()); |
| 28 | |
| 29 | if let Some(v) = installed.last() { |
| 30 | let t = Instant::now(); |
| 31 | let plan = nox_roblox::launch::plan(&root, v, nox_roblox::Binary::Player, Some("roblox-player:1+launchmode:play")); |
| 32 | let planning = t.elapsed().as_secs_f64() * 1000.0; |
| 33 | println!("building the launch plan: {planning:.3} ms"); |
| 34 | println!("would exec: {} {:?}", plan.exe.display(), plan.args); |
| 35 | println!("total launcher-side work on the instant path: {:.2} ms", scan + planning); |
| 36 | } |
| 37 | } |
| 38 | |
| 39 | fn dirs_root() -> std::path::PathBuf { |
| 40 | std::env::var("HOME") |
| 41 | .map(std::path::PathBuf::from) |
| 42 | .unwrap_or_default() |
| 43 | .join(".local/share/noxstrap") |
| 44 | } |