lean_ctx/core/benchmark_compare/
system_info.rs1use std::fmt;
2
3#[derive(Debug, Clone)]
4pub struct SystemInfo {
5 pub os: String,
6 pub arch: String,
7 pub cpu_brand: String,
8 pub cpu_cores: usize,
9 pub memory_gb: f64,
10 pub lean_ctx_version: String,
11 pub rust_version: String,
12}
13
14impl fmt::Display for SystemInfo {
15 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16 write!(
17 f,
18 "{} {} | {} ({} cores) | {:.1} GB RAM",
19 self.os, self.arch, self.cpu_brand, self.cpu_cores, self.memory_gb
20 )
21 }
22}
23
24pub fn collect() -> SystemInfo {
25 SystemInfo {
26 os: std::env::consts::OS.to_string(),
27 arch: std::env::consts::ARCH.to_string(),
28 cpu_brand: read_cpu_brand(),
29 cpu_cores: std::thread::available_parallelism().map_or(1, std::num::NonZero::get),
30 memory_gb: read_memory_gb(),
31 lean_ctx_version: env!("CARGO_PKG_VERSION").to_string(),
32 rust_version: read_rust_version(),
33 }
34}
35
36fn read_cpu_brand() -> String {
37 #[cfg(target_os = "macos")]
38 {
39 std::process::Command::new("sysctl")
40 .args(["-n", "machdep.cpu.brand_string"])
41 .output()
42 .ok()
43 .and_then(|o| String::from_utf8(o.stdout).ok())
44 .map_or_else(|| "Unknown CPU".to_string(), |s| s.trim().to_string())
45 }
46 #[cfg(target_os = "linux")]
47 {
48 std::fs::read_to_string("/proc/cpuinfo")
49 .ok()
50 .and_then(|s| {
51 s.lines()
52 .find(|l| l.starts_with("model name"))
53 .and_then(|l| l.split(':').nth(1))
54 .map(|v| v.trim().to_string())
55 })
56 .unwrap_or_else(|| "Unknown CPU".to_string())
57 }
58 #[cfg(target_os = "windows")]
59 {
60 std::process::Command::new("powershell")
61 .args([
62 "-NoProfile",
63 "-Command",
64 "(Get-CimInstance Win32_Processor).Name",
65 ])
66 .output()
67 .ok()
68 .and_then(|o| String::from_utf8(o.stdout).ok())
69 .map(|s| s.trim().to_string())
70 .filter(|s| !s.is_empty())
71 .unwrap_or_else(|| "Unknown CPU".to_string())
72 }
73 #[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))]
74 {
75 "Unknown CPU".to_string()
76 }
77}
78
79fn read_memory_gb() -> f64 {
80 #[cfg(target_os = "macos")]
81 {
82 std::process::Command::new("sysctl")
83 .args(["-n", "hw.memsize"])
84 .output()
85 .ok()
86 .and_then(|o| String::from_utf8(o.stdout).ok())
87 .and_then(|s| s.trim().parse::<u64>().ok())
88 .map_or(0.0, |bytes| bytes as f64 / (1024.0 * 1024.0 * 1024.0))
89 }
90 #[cfg(target_os = "linux")]
91 {
92 std::fs::read_to_string("/proc/meminfo")
93 .ok()
94 .and_then(|s| {
95 s.lines().find(|l| l.starts_with("MemTotal")).and_then(|l| {
96 l.split_whitespace()
97 .nth(1)
98 .and_then(|v| v.parse::<u64>().ok())
99 })
100 })
101 .map_or(0.0, |kb| kb as f64 / (1024.0 * 1024.0))
102 }
103 #[cfg(target_os = "windows")]
104 {
105 std::process::Command::new("powershell")
108 .args([
109 "-NoProfile",
110 "-Command",
111 "(Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory",
112 ])
113 .output()
114 .ok()
115 .and_then(|o| String::from_utf8(o.stdout).ok())
116 .and_then(|s| s.trim().parse::<u64>().ok())
117 .map_or(0.0, |bytes| bytes as f64 / (1024.0 * 1024.0 * 1024.0))
118 }
119 #[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))]
120 {
121 0.0
122 }
123}
124
125fn read_rust_version() -> String {
126 std::process::Command::new("rustc")
127 .arg("--version")
128 .output()
129 .ok()
130 .and_then(|o| String::from_utf8(o.stdout).ok())
131 .map_or_else(|| "unknown".to_string(), |s| s.trim().to_string())
132}
133
134#[cfg(test)]
135mod tests {
136 use super::*;
137
138 #[test]
139 fn collect_returns_valid_info() {
140 let info = collect();
141 assert!(!info.os.is_empty());
142 assert!(!info.arch.is_empty());
143 assert!(!info.lean_ctx_version.is_empty());
144 assert!(info.cpu_cores >= 1);
145 }
146
147 #[test]
148 fn display_is_readable() {
149 let info = collect();
150 let s = format!("{info}");
151 assert!(s.contains(&info.os));
152 assert!(s.contains("cores"));
153 }
154}