返回 CodeWhale
zz_perf_probe.rs
根目录 / crates / tui / examples / zz_perf_probe.rs
1 use codewhale_models::Message;
2 use codewhale_runtime::session_tree;
3 use serde::{Deserialize, Serialize};
4 use session_tree::SessionJournal;
5 use std::io::Write;
6 use std::time::Instant;
7
8 #[derive(Debug, Clone, Serialize, Deserialize)]
9 struct Probe {
10 #[serde(default)]
11 schema_version: u32,
12 metadata: serde_json::Value,
13 messages: Vec<Message>,
14 #[serde(default, skip_serializing_if = "Option::is_none")]
15 journal: Option<SessionJournal>,
16 #[serde(default, skip_serializing_if = "Option::is_none")]
17 leaf_id: Option<String>,
18 #[serde(default)]
19 system_prompt: Option<String>,
20 #[serde(flatten)]
21 rest: serde_json::Map<String, serde_json::Value>,
22 }
23
24 fn main() {
25 let path = std::env::args().nth(1).expect("path");
26 let raw = std::fs::read_to_string(&path).unwrap();
27 println!("file bytes: {}", raw.len());
28
29 let t = Instant::now();
30 let s: Probe = serde_json::from_str(&raw).unwrap();
31 println!("typed parse: {:?}", t.elapsed());
32 println!(
33 "messages: {} journal entries: {}",
34 s.messages.len(),
35 s.journal.as_ref().map(|j| j.entries.len()).unwrap_or(0)
36 );
37
38 for _ in 0..3 {
39 let t = Instant::now();
40 let out = serde_json::to_string_pretty(&s).unwrap();
41 println!(
42 "to_string_pretty FULL: {:?} ({} bytes)",
43 t.elapsed(),
44 out.len()
45 );
46 }
47 let mut dedup = s.clone();
48 dedup.messages = Vec::new();
49 for _ in 0..3 {
50 let t = Instant::now();
51 let out = serde_json::to_string_pretty(&dedup).unwrap();
52 println!(
53 "to_string_pretty JOURNAL-ONLY: {:?} ({} bytes)",
54 t.elapsed(),
55 out.len()
56 );
57 }
58 for _ in 0..3 {
59 let t = Instant::now();
60 let c = s.clone();
61 println!(
62 "Probe::clone (== SavedSession::clone): {:?} ({} msgs)",
63 t.elapsed(),
64 c.messages.len()
65 );
66 }
67 let j = s.journal.as_ref().unwrap();
68 for _ in 0..3 {
69 let t = Instant::now();
70 let m = j.to_messages();
71 println!(
72 "journal.to_messages (deep clone): {:?} ({} msgs)",
73 t.elapsed(),
74 m.len()
75 );
76 }
77 for _ in 0..3 {
78 let t = Instant::now();
79 let jj = SessionJournal::from_messages(s.messages.clone(), 0);
80 println!(
81 "from_messages(messages.to_vec()) [UI-thread snapshot build]: {:?} ({} entries)",
82 t.elapsed(),
83 jj.entries.len()
84 );
85 }
86 for _ in 0..3 {
87 let t = Instant::now();
88 let eq = s.messages == j.to_messages();
89 println!(
90 "storage_compatible_copy compare: {:?} (eq={})",
91 t.elapsed(),
92 eq
93 );
94 }
95 let content = serde_json::to_string_pretty(&s).unwrap();
96 let dir = std::env::temp_dir();
97 for _ in 0..3 {
98 let t = Instant::now();
99 let mut f = tempfile::NamedTempFile::new_in(&dir).unwrap();
100 f.write_all(content.as_bytes()).unwrap();
101 f.as_file().sync_all().unwrap();
102 let p = dir.join("zz_perf_probe_out.json");
103 f.persist(&p).unwrap();
104 println!(
105 "atomic write+fsync {} bytes: {:?}",
106 content.len(),
107 t.elapsed()
108 );
109 }
110 let dc = serde_json::to_string_pretty(&dedup).unwrap();
111 for _ in 0..3 {
112 let t = Instant::now();
113 let mut f = tempfile::NamedTempFile::new_in(&dir).unwrap();
114 f.write_all(dc.as_bytes()).unwrap();
115 f.as_file().sync_all().unwrap();
116 let p = dir.join("zz_perf_probe_out2.json");
117 f.persist(&p).unwrap();
118 println!(
119 "atomic write+fsync DEDUP {} bytes: {:?}",
120 dc.len(),
121 t.elapsed()
122 );
123 }
124 }
125
125 lines RUST