Skip to content

Commit c60b682

Browse files
authored
add progress and top self time to convert trace tool (vercel/turborepo#5993)
### Description add progress add top 10 self time spans Closes WEB-1624
1 parent 917ade8 commit c60b682

File tree

1 file changed

+83
-21
lines changed
  • crates/turbopack-convert-trace/src

1 file changed

+83
-21
lines changed

crates/turbopack-convert-trace/src/main.rs

Lines changed: 83 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use std::{
3030
cmp::{max, min, Reverse},
3131
collections::{hash_map::Entry, HashMap, HashSet},
3232
eprintln,
33+
io::{stderr, Write},
3334
mem::take,
3435
ops::Range,
3536
time::Instant,
@@ -100,7 +101,10 @@ fn main() {
100101
start.elapsed().as_secs_f32()
101102
);
102103

103-
eprint!("Analysing trace into span tree...");
104+
eprint!(
105+
"Analysing trace into span tree... 0 / {} (0%)",
106+
trace_rows.len()
107+
);
104108
let start = Instant::now();
105109

106110
let mut spans = Vec::new();
@@ -112,6 +116,7 @@ fn main() {
112116
start: 0,
113117
end: 0,
114118
self_start: None,
119+
self_time: 0,
115120
items: Vec::new(),
116121
values: IndexMap::new(),
117122
});
@@ -132,6 +137,7 @@ fn main() {
132137
start: 0,
133138
end: 0,
134139
self_start: None,
140+
self_time: 0,
135141
items: Vec::new(),
136142
values: IndexMap::new(),
137143
};
@@ -143,22 +149,47 @@ fn main() {
143149

144150
let mut all_self_times = Vec::new();
145151
let mut name_counts: HashMap<Cow<'_, str>, usize> = HashMap::new();
152+
let mut name_self_times: HashMap<Cow<'_, str>, u64> = HashMap::new();
146153

147154
fn get_name<'a>(
148155
name: &'a str,
149156
values: &IndexMap<Cow<'a, str>, TraceValue<'a>>,
150157
collapse_names: bool,
151158
) -> Cow<'a, str> {
152-
if collapse_names && name != "turbo_tasks::function" {
159+
if name == "turbo_tasks::function" {
160+
if let Some(v) = values.get("name") {
161+
return format!("{v} ({name})").into();
162+
} else {
163+
return name.into();
164+
}
165+
}
166+
if collapse_names || values.is_empty() {
153167
return name.into();
154168
}
155-
values
156-
.get("name")
157-
.and_then(|v| v.as_str().map(|s| format!("{s} ({name})").into()))
158-
.unwrap_or(name.into())
169+
let mut name = name.to_string();
170+
name.push_str(" (");
171+
for (i, (key, value)) in values.iter().enumerate() {
172+
use std::fmt::Write;
173+
if i > 0 {
174+
name.push_str(", ");
175+
}
176+
write!(name, "{key}={value}").unwrap();
177+
}
178+
name.push(')');
179+
name.into()
159180
}
160181

161-
for data in trace_rows {
182+
let number_of_trace_rows = trace_rows.len();
183+
for (i, data) in trace_rows.into_iter().enumerate() {
184+
if i % 131072 == 0 {
185+
eprint!(
186+
"\rAnalysing trace into span tree... {} / {} ({}%)",
187+
i,
188+
number_of_trace_rows,
189+
i * 100 / number_of_trace_rows
190+
);
191+
let _ = stderr().flush();
192+
}
162193
match data {
163194
TraceRow::Start {
164195
ts,
@@ -216,6 +247,8 @@ fn main() {
216247
value: internal_id,
217248
});
218249
}
250+
span.self_time += duration;
251+
*name_self_times.entry(span.name.clone()).or_default() += duration;
219252
}
220253
}
221254
TraceRow::Event { ts, parent, values } => {
@@ -238,6 +271,7 @@ fn main() {
238271
start,
239272
end: ts,
240273
self_start: None,
274+
self_time: 0,
241275
items: vec![SpanItem::SelfTime { start, duration }],
242276
values,
243277
});
@@ -254,7 +288,9 @@ fn main() {
254288
}
255289

256290
eprintln!(
257-
" done ({} spans, {:.3}s)",
291+
"\rAnalysing trace into span tree... {} / {} done ({} spans, {:.3}s)",
292+
number_of_trace_rows,
293+
number_of_trace_rows,
258294
spans.len(),
259295
start.elapsed().as_secs_f64()
260296
);
@@ -292,8 +328,8 @@ fn main() {
292328
.map(|span| &*span.name)
293329
.collect::<Vec<_>>();
294330
if parents.len() > 10 {
295-
parents.drain(10..parents.len() - 10);
296-
parents.insert(10, "...")
331+
parents.drain(5..parents.len() - 5);
332+
parents.insert(5, "...")
297333
}
298334
let message = parents
299335
.into_iter()
@@ -312,6 +348,14 @@ fn main() {
312348
eprintln!("{}x {}", count, name);
313349
}
314350

351+
let mut name_self_times: Vec<(Cow<'_, str>, u64)> = name_self_times.into_iter().collect();
352+
name_self_times.sort_by_key(|(_, duration)| Reverse(*duration));
353+
354+
eprintln!("Top 10 span durations:");
355+
for (name, duration) in name_self_times.into_iter().take(10) {
356+
eprintln!("{}s {}", duration / 1000 / 1000, name);
357+
}
358+
315359
println!("[");
316360
print!(r#"{{"ph":"M","pid":1,"name":"thread_name","tid":0,"args":{{"name":"Single CPU"}}}}"#);
317361
pjson!(r#"{{"ph":"M","pid":2,"name":"thread_name","tid":0,"args":{{"name":"Scaling CPU"}}}}"#);
@@ -374,6 +418,7 @@ fn main() {
374418
{
375419
if i % 1000 == 0 {
376420
eprint!("\rDistributing time into virtual threads... {i} / {busy_len}",);
421+
let _ = stderr().flush();
377422
}
378423
let stack = get_stack(id);
379424
let thread = find_thread(&mut virtual_threads, &stack, start);
@@ -440,9 +485,25 @@ fn main() {
440485
}
441486

442487
if single || merged {
443-
eprint!("Emitting span tree...");
444-
let start = Instant::now();
488+
let number_of_spans = spans.len();
489+
eprint!("Emitting span tree... 0 / {} (0%)", number_of_spans);
445490
let mut span_counter = 0;
491+
let mut add_to_span_counter = {
492+
let span_counter = &mut span_counter;
493+
|| {
494+
*span_counter += 1;
495+
if *span_counter % 16384 == 0 {
496+
eprint!(
497+
"\rEmitting span tree... {} / {} ({}%)",
498+
*span_counter,
499+
number_of_spans,
500+
*span_counter * 100 / number_of_spans
501+
);
502+
let _ = stderr().flush();
503+
}
504+
}
505+
};
506+
let start = Instant::now();
446507

447508
const CONCURRENCY_FIXED_POINT_FACTOR: u64 = 100;
448509
const CONCURRENCY_FIXED_POINT_FACTOR_F: f32 = 100.0;
@@ -490,7 +551,7 @@ fn main() {
490551
.rev()
491552
.filter_map(|(id, span)| {
492553
if span.parent == 0 {
493-
span_counter += 1;
554+
add_to_span_counter();
494555
Some(Task::Enter { id, root: true })
495556
} else {
496557
None
@@ -514,6 +575,7 @@ fn main() {
514575
parent_count: &mut u32,
515576
parent_name: &str,
516577
items: Vec<SpanItem>,
578+
add_to_span_counter: &mut impl FnMut(),
517579
) {
518580
for item in items {
519581
match item {
@@ -533,9 +595,14 @@ fn main() {
533595
parent_count,
534596
parent_name,
535597
items,
598+
add_to_span_counter,
536599
);
600+
add_to_span_counter();
537601
} else {
538602
let group = groups.entry(key).or_insert_with(Vec::new);
603+
if !group.is_empty() {
604+
add_to_span_counter();
605+
}
539606
group.push(item);
540607
}
541608
}
@@ -549,6 +616,7 @@ fn main() {
549616
&mut count,
550617
parent_name,
551618
items,
619+
&mut add_to_span_counter,
552620
);
553621
if !self_items.is_empty() {
554622
groups
@@ -656,14 +724,7 @@ fn main() {
656724
}
657725
}
658726
SpanItem::Child(id) => {
659-
span_counter += 1;
660-
if span_counter % 12543 == 0 {
661-
eprint!(
662-
"\rEmitting span tree... {} / {}",
663-
span_counter,
664-
spans.len()
665-
);
666-
}
727+
add_to_span_counter();
667728
stack.push(Task::Enter {
668729
id: *id,
669730
root: false,
@@ -776,6 +837,7 @@ struct Span<'a> {
776837
start: u64,
777838
end: u64,
778839
self_start: Option<SelfTimeStarted>,
840+
self_time: u64,
779841
items: Vec<SpanItem>,
780842
values: IndexMap<Cow<'a, str>, TraceValue<'a>>,
781843
}

0 commit comments

Comments
 (0)