@@ -30,6 +30,7 @@ use std::{
30
30
cmp:: { max, min, Reverse } ,
31
31
collections:: { hash_map:: Entry , HashMap , HashSet } ,
32
32
eprintln,
33
+ io:: { stderr, Write } ,
33
34
mem:: take,
34
35
ops:: Range ,
35
36
time:: Instant ,
@@ -100,7 +101,10 @@ fn main() {
100
101
start. elapsed( ) . as_secs_f32( )
101
102
) ;
102
103
103
- eprint ! ( "Analysing trace into span tree..." ) ;
104
+ eprint ! (
105
+ "Analysing trace into span tree... 0 / {} (0%)" ,
106
+ trace_rows. len( )
107
+ ) ;
104
108
let start = Instant :: now ( ) ;
105
109
106
110
let mut spans = Vec :: new ( ) ;
@@ -112,6 +116,7 @@ fn main() {
112
116
start : 0 ,
113
117
end : 0 ,
114
118
self_start : None ,
119
+ self_time : 0 ,
115
120
items : Vec :: new ( ) ,
116
121
values : IndexMap :: new ( ) ,
117
122
} ) ;
@@ -132,6 +137,7 @@ fn main() {
132
137
start : 0 ,
133
138
end : 0 ,
134
139
self_start : None ,
140
+ self_time : 0 ,
135
141
items : Vec :: new ( ) ,
136
142
values : IndexMap :: new ( ) ,
137
143
} ;
@@ -143,22 +149,47 @@ fn main() {
143
149
144
150
let mut all_self_times = Vec :: new ( ) ;
145
151
let mut name_counts: HashMap < Cow < ' _ , str > , usize > = HashMap :: new ( ) ;
152
+ let mut name_self_times: HashMap < Cow < ' _ , str > , u64 > = HashMap :: new ( ) ;
146
153
147
154
fn get_name < ' a > (
148
155
name : & ' a str ,
149
156
values : & IndexMap < Cow < ' a , str > , TraceValue < ' a > > ,
150
157
collapse_names : bool ,
151
158
) -> 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 ( ) {
153
167
return name. into ( ) ;
154
168
}
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 ( )
159
180
}
160
181
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
+ "\r Analysing trace into span tree... {} / {} ({}%)" ,
187
+ i,
188
+ number_of_trace_rows,
189
+ i * 100 / number_of_trace_rows
190
+ ) ;
191
+ let _ = stderr ( ) . flush ( ) ;
192
+ }
162
193
match data {
163
194
TraceRow :: Start {
164
195
ts,
@@ -216,6 +247,8 @@ fn main() {
216
247
value : internal_id,
217
248
} ) ;
218
249
}
250
+ span. self_time += duration;
251
+ * name_self_times. entry ( span. name . clone ( ) ) . or_default ( ) += duration;
219
252
}
220
253
}
221
254
TraceRow :: Event { ts, parent, values } => {
@@ -238,6 +271,7 @@ fn main() {
238
271
start,
239
272
end : ts,
240
273
self_start : None ,
274
+ self_time : 0 ,
241
275
items : vec ! [ SpanItem :: SelfTime { start, duration } ] ,
242
276
values,
243
277
} ) ;
@@ -254,7 +288,9 @@ fn main() {
254
288
}
255
289
256
290
eprintln ! (
257
- " done ({} spans, {:.3}s)" ,
291
+ "\r Analysing trace into span tree... {} / {} done ({} spans, {:.3}s)" ,
292
+ number_of_trace_rows,
293
+ number_of_trace_rows,
258
294
spans. len( ) ,
259
295
start. elapsed( ) . as_secs_f64( )
260
296
) ;
@@ -292,8 +328,8 @@ fn main() {
292
328
. map ( |span| & * span. name )
293
329
. collect :: < Vec < _ > > ( ) ;
294
330
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 , "..." )
297
333
}
298
334
let message = parents
299
335
. into_iter ( )
@@ -312,6 +348,14 @@ fn main() {
312
348
eprintln ! ( "{}x {}" , count, name) ;
313
349
}
314
350
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
+
315
359
println ! ( "[" ) ;
316
360
print ! ( r#"{{"ph":"M","pid":1,"name":"thread_name","tid":0,"args":{{"name":"Single CPU"}}}}"# ) ;
317
361
pjson ! ( r#"{{"ph":"M","pid":2,"name":"thread_name","tid":0,"args":{{"name":"Scaling CPU"}}}}"# ) ;
@@ -374,6 +418,7 @@ fn main() {
374
418
{
375
419
if i % 1000 == 0 {
376
420
eprint ! ( "\r Distributing time into virtual threads... {i} / {busy_len}" , ) ;
421
+ let _ = stderr ( ) . flush ( ) ;
377
422
}
378
423
let stack = get_stack ( id) ;
379
424
let thread = find_thread ( & mut virtual_threads, & stack, start) ;
@@ -440,9 +485,25 @@ fn main() {
440
485
}
441
486
442
487
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 ) ;
445
490
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
+ "\r Emitting 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 ( ) ;
446
507
447
508
const CONCURRENCY_FIXED_POINT_FACTOR : u64 = 100 ;
448
509
const CONCURRENCY_FIXED_POINT_FACTOR_F : f32 = 100.0 ;
@@ -490,7 +551,7 @@ fn main() {
490
551
. rev ( )
491
552
. filter_map ( |( id, span) | {
492
553
if span. parent == 0 {
493
- span_counter += 1 ;
554
+ add_to_span_counter ( ) ;
494
555
Some ( Task :: Enter { id, root : true } )
495
556
} else {
496
557
None
@@ -514,6 +575,7 @@ fn main() {
514
575
parent_count : & mut u32 ,
515
576
parent_name : & str ,
516
577
items : Vec < SpanItem > ,
578
+ add_to_span_counter : & mut impl FnMut ( ) ,
517
579
) {
518
580
for item in items {
519
581
match item {
@@ -533,9 +595,14 @@ fn main() {
533
595
parent_count,
534
596
parent_name,
535
597
items,
598
+ add_to_span_counter,
536
599
) ;
600
+ add_to_span_counter ( ) ;
537
601
} else {
538
602
let group = groups. entry ( key) . or_insert_with ( Vec :: new) ;
603
+ if !group. is_empty ( ) {
604
+ add_to_span_counter ( ) ;
605
+ }
539
606
group. push ( item) ;
540
607
}
541
608
}
@@ -549,6 +616,7 @@ fn main() {
549
616
& mut count,
550
617
parent_name,
551
618
items,
619
+ & mut add_to_span_counter,
552
620
) ;
553
621
if !self_items. is_empty ( ) {
554
622
groups
@@ -656,14 +724,7 @@ fn main() {
656
724
}
657
725
}
658
726
SpanItem :: Child ( id) => {
659
- span_counter += 1 ;
660
- if span_counter % 12543 == 0 {
661
- eprint ! (
662
- "\r Emitting span tree... {} / {}" ,
663
- span_counter,
664
- spans. len( )
665
- ) ;
666
- }
727
+ add_to_span_counter ( ) ;
667
728
stack. push ( Task :: Enter {
668
729
id : * id,
669
730
root : false ,
@@ -776,6 +837,7 @@ struct Span<'a> {
776
837
start : u64 ,
777
838
end : u64 ,
778
839
self_start : Option < SelfTimeStarted > ,
840
+ self_time : u64 ,
779
841
items : Vec < SpanItem > ,
780
842
values : IndexMap < Cow < ' a , str > , TraceValue < ' a > > ,
781
843
}
0 commit comments