1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
use measurement::{self, Measurement};
use format::{self, FormattingOptions};
pub fn print() {
print_with_format(format::STREAMLINED, 0);
}
pub fn print_with_format(ops: FormattingOptions, decimals: usize) {
println!("{}", get_formatted_string(ops, decimals));
}
pub fn get_formatted_string(ops: FormattingOptions, decimals: usize) -> String {
let mut result = String::new();
let children = measurement::get_measures();
let construct_tree_branch = |measurement: &Measurement| -> String {
let has_child;
let not_last_leaf;
if let Some(ref parent) = measurement.parent {
let parent = parent.get_mut();
has_child = measurement.has_children();
not_last_leaf = !parent.is_last_child_name(&measurement.name, true);
} else {
has_child = false;
not_last_leaf = false;
}
let mut branch = String::new();
for d in 0..measurement.depth {
if d == measurement.depth - 1 {
branch += if measurement.depth == 1 {
ops.starting_branch
} else if not_last_leaf {
ops.branching_branch
} else {
ops.turning_branch
}
} else {
let width =
ops.ending_branch.chars().count() - ops.continuing_branch.chars().count();
let mut branch_part = format!("{:width$}", "", width = width);
let generation = (measurement.depth - 1 - d) as u32;
if d > 0 && generation >= 1 {
if let Some(ancestor) = measurement.get_ancestor(generation) {
let ancestor = ancestor.get_mut();
let younger_ancestor = measurement.get_ancestor(generation - 1).unwrap();
let younger_ancestor = younger_ancestor.get_mut();
if !ancestor.is_last_child_name(&younger_ancestor.name, false) {
branch_part =
format!("{:width$}", ops.continuing_branch, width = width);
}
}
}
branch += &branch_part
}
}
branch += if has_child {
ops.turning_ending_branch
} else {
ops.ending_branch
};
branch += " ";
branch += &measurement.name;
branch
};
let mut max_width = 0;
for measurement in &children {
let width = construct_tree_branch(&measurement).chars().count() + 1;
if width > max_width {
max_width = width;
}
}
let mut index = 0;
let mut main_count = 1;
for measurement in children {
if index == 0 {
index = 1;
continue;
}
let branch = construct_tree_branch(&measurement);
let info_line;
if let Some(duration) = measurement.get_duration_ns() {
let count = measurement.durations.len();
let parent_duration = if measurement.depth > 1 {
let parent = measurement.parent.unwrap();
let parent = parent.get_mut();
match parent.get_duration_ns() {
Some(duration) => duration,
None => duration,
}
} else {
duration
};
if measurement.depth == 1 {
main_count = count;
}
info_line = format!(
"{:5.1}%, {:width$.decimals$} ms/loop, {} samples",
100.0 * (duration as f64 / parent_duration as f64),
(duration / main_count as u64) as f64 / 1_000_000.0,
count,
width = decimals + 3,
decimals = decimals
);
} else {
info_line = String::from("no data");
}
result += &format!(
"{:max_width$} - {}\n",
branch,
info_line,
max_width = max_width
);
index += 1;
}
result
}