@@ -9,7 +9,6 @@ use std::{
9
9
collections:: BTreeMap ,
10
10
collections:: HashSet ,
11
11
io:: { stderr, Write } ,
12
- mem,
13
12
sync:: {
14
13
atomic:: { AtomicBool , Ordering } ,
15
14
RwLock ,
@@ -50,6 +49,8 @@ pub fn set_filter(f: Filter) {
50
49
* old = filter_data;
51
50
}
52
51
52
+ pub type Label = & ' static str ;
53
+
53
54
/// This function starts a profiling scope in the current execution stack with a given description.
54
55
/// It returns a Profile structure and measure elapsed time between this method invocation and Profile structure drop.
55
56
/// It supports nested profiling scopes in case when this function invoked multiple times at the execution stack. In this case the profiling information will be nested at the output.
@@ -77,10 +78,10 @@ pub fn set_filter(f: Filter) {
77
78
/// 0ms - profile
78
79
/// 0ms - profile2
79
80
/// ```
80
- pub fn profile ( desc : & str ) -> Profiler {
81
- assert ! ( !desc . is_empty( ) ) ;
81
+ pub fn profile ( label : Label ) -> Profiler {
82
+ assert ! ( !label . is_empty( ) ) ;
82
83
if !PROFILING_ENABLED . load ( Ordering :: Relaxed ) {
83
- return Profiler { desc : None } ;
84
+ return Profiler { label : None } ;
84
85
}
85
86
86
87
PROFILE_STACK . with ( |stack| {
@@ -93,35 +94,35 @@ pub fn profile(desc: &str) -> Profiler {
93
94
} ;
94
95
}
95
96
if stack. starts . len ( ) > stack. filter_data . depth {
96
- return Profiler { desc : None } ;
97
+ return Profiler { label : None } ;
97
98
}
98
99
let allowed = & stack. filter_data . allowed ;
99
- if stack. starts . is_empty ( ) && !allowed. is_empty ( ) && !allowed. contains ( desc ) {
100
- return Profiler { desc : None } ;
100
+ if stack. starts . is_empty ( ) && !allowed. is_empty ( ) && !allowed. contains ( label ) {
101
+ return Profiler { label : None } ;
101
102
}
102
103
103
104
stack. starts . push ( Instant :: now ( ) ) ;
104
- Profiler { desc : Some ( desc . to_string ( ) ) }
105
+ Profiler { label : Some ( label ) }
105
106
} )
106
107
}
107
108
108
- pub fn print_time ( desc : & str ) -> impl Drop + ' _ {
109
- struct Guard < ' a > {
110
- desc : & ' a str ,
109
+ pub fn print_time ( label : Label ) -> impl Drop {
110
+ struct Guard {
111
+ label : Label ,
111
112
start : Instant ,
112
113
}
113
114
114
- impl Drop for Guard < ' _ > {
115
+ impl Drop for Guard {
115
116
fn drop ( & mut self ) {
116
- eprintln ! ( "{}: {:?}" , self . desc , self . start. elapsed( ) )
117
+ eprintln ! ( "{}: {:?}" , self . label , self . start. elapsed( ) )
117
118
}
118
119
}
119
120
120
- Guard { desc , start : Instant :: now ( ) }
121
+ Guard { label , start : Instant :: now ( ) }
121
122
}
122
123
123
124
pub struct Profiler {
124
- desc : Option < String > ,
125
+ label : Option < Label > ,
125
126
}
126
127
127
128
pub struct Filter {
@@ -174,7 +175,7 @@ struct ProfileStack {
174
175
struct Message {
175
176
level : usize ,
176
177
duration : Duration ,
177
- message : String ,
178
+ label : Label ,
178
179
}
179
180
180
181
impl ProfileStack {
@@ -200,14 +201,13 @@ thread_local!(static PROFILE_STACK: RefCell<ProfileStack> = RefCell::new(Profile
200
201
impl Drop for Profiler {
201
202
fn drop ( & mut self ) {
202
203
match self {
203
- Profiler { desc : Some ( desc ) } => {
204
+ Profiler { label : Some ( label ) } => {
204
205
PROFILE_STACK . with ( |stack| {
205
206
let mut stack = stack. borrow_mut ( ) ;
206
207
let start = stack. starts . pop ( ) . unwrap ( ) ;
207
208
let duration = start. elapsed ( ) ;
208
209
let level = stack. starts . len ( ) ;
209
- let message = mem:: replace ( desc, String :: new ( ) ) ;
210
- stack. messages . push ( Message { level, duration, message } ) ;
210
+ stack. messages . push ( Message { level, duration, label : label } ) ;
211
211
if level == 0 {
212
212
let stdout = stderr ( ) ;
213
213
let longer_than = stack. filter_data . longer_than ;
@@ -221,7 +221,7 @@ impl Drop for Profiler {
221
221
}
222
222
} ) ;
223
223
}
224
- Profiler { desc : None } => ( ) ,
224
+ Profiler { label : None } => ( ) ,
225
225
}
226
226
}
227
227
}
@@ -244,7 +244,7 @@ fn print_for_idx(
244
244
) {
245
245
let current = & msgs[ current_idx] ;
246
246
let current_indent = " " . repeat ( current. level ) ;
247
- writeln ! ( out, "{}{:5}ms - {}" , current_indent, current. duration. as_millis( ) , current. message )
247
+ writeln ! ( out, "{}{:5}ms - {}" , current_indent, current. duration. as_millis( ) , current. label )
248
248
. expect ( "printing profiling info" ) ;
249
249
250
250
let longer_than_millis = longer_than. as_millis ( ) ;
@@ -257,7 +257,7 @@ fn print_for_idx(
257
257
if child. duration . as_millis ( ) > longer_than_millis {
258
258
print_for_idx ( * child_idx, children_map, msgs, longer_than, out) ;
259
259
} else {
260
- let pair = short_children. entry ( & child. message ) . or_insert ( ( Duration :: default ( ) , 0 ) ) ;
260
+ let pair = short_children. entry ( child. label ) . or_insert ( ( Duration :: default ( ) , 0 ) ) ;
261
261
pair. 0 += child. duration ;
262
262
pair. 1 += 1 ;
263
263
}
@@ -409,9 +409,9 @@ mod tests {
409
409
fn test_longer_than ( ) {
410
410
let mut result = vec ! [ ] ;
411
411
let msgs = vec ! [
412
- Message { level: 1 , duration: Duration :: from_nanos( 3 ) , message : "bar" . to_owned ( ) } ,
413
- Message { level: 1 , duration: Duration :: from_nanos( 2 ) , message : "bar" . to_owned ( ) } ,
414
- Message { level: 0 , duration: Duration :: from_millis( 1 ) , message : "foo" . to_owned ( ) } ,
412
+ Message { level: 1 , duration: Duration :: from_nanos( 3 ) , label : "bar" } ,
413
+ Message { level: 1 , duration: Duration :: from_nanos( 2 ) , label : "bar" } ,
414
+ Message { level: 0 , duration: Duration :: from_millis( 1 ) , label : "foo" } ,
415
415
] ;
416
416
print ( & msgs, Duration :: from_millis ( 0 ) , & mut result) ;
417
417
// The calls to `bar` are so short that they'll be rounded to 0ms and should get collapsed
@@ -426,8 +426,8 @@ mod tests {
426
426
fn test_unaccounted_for_topmost ( ) {
427
427
let mut result = vec ! [ ] ;
428
428
let msgs = vec ! [
429
- Message { level: 1 , duration: Duration :: from_millis( 2 ) , message : "bar" . to_owned ( ) } ,
430
- Message { level: 0 , duration: Duration :: from_millis( 5 ) , message : "foo" . to_owned ( ) } ,
429
+ Message { level: 1 , duration: Duration :: from_millis( 2 ) , label : "bar" } ,
430
+ Message { level: 0 , duration: Duration :: from_millis( 5 ) , label : "foo" } ,
431
431
] ;
432
432
print ( & msgs, Duration :: from_millis ( 0 ) , & mut result) ;
433
433
assert_eq ! (
@@ -445,11 +445,11 @@ mod tests {
445
445
fn test_unaccounted_for_multiple_levels ( ) {
446
446
let mut result = vec ! [ ] ;
447
447
let msgs = vec ! [
448
- Message { level: 2 , duration: Duration :: from_millis( 3 ) , message : "baz" . to_owned ( ) } ,
449
- Message { level: 1 , duration: Duration :: from_millis( 5 ) , message : "bar" . to_owned ( ) } ,
450
- Message { level: 2 , duration: Duration :: from_millis( 2 ) , message : "baz" . to_owned ( ) } ,
451
- Message { level: 1 , duration: Duration :: from_millis( 4 ) , message : "bar" . to_owned ( ) } ,
452
- Message { level: 0 , duration: Duration :: from_millis( 9 ) , message : "foo" . to_owned ( ) } ,
448
+ Message { level: 2 , duration: Duration :: from_millis( 3 ) , label : "baz" } ,
449
+ Message { level: 1 , duration: Duration :: from_millis( 5 ) , label : "bar" } ,
450
+ Message { level: 2 , duration: Duration :: from_millis( 2 ) , label : "baz" } ,
451
+ Message { level: 1 , duration: Duration :: from_millis( 4 ) , label : "bar" } ,
452
+ Message { level: 0 , duration: Duration :: from_millis( 9 ) , label : "foo" } ,
453
453
] ;
454
454
print ( & msgs, Duration :: from_millis ( 0 ) , & mut result) ;
455
455
assert_eq ! (
0 commit comments