@@ -9,7 +9,6 @@ use std::{
99 collections:: BTreeMap ,
1010 collections:: HashSet ,
1111 io:: { stderr, Write } ,
12- mem,
1312 sync:: {
1413 atomic:: { AtomicBool , Ordering } ,
1514 RwLock ,
@@ -50,6 +49,8 @@ pub fn set_filter(f: Filter) {
5049 * old = filter_data;
5150}
5251
52+ pub type Label = & ' static str ;
53+
5354/// This function starts a profiling scope in the current execution stack with a given description.
5455/// It returns a Profile structure and measure elapsed time between this method invocation and Profile structure drop.
5556/// 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) {
7778/// 0ms - profile
7879/// 0ms - profile2
7980/// ```
80- pub fn profile ( desc : & str ) -> Profiler {
81- assert ! ( !desc . is_empty( ) ) ;
81+ pub fn profile ( label : Label ) -> Profiler {
82+ assert ! ( !label . is_empty( ) ) ;
8283 if !PROFILING_ENABLED . load ( Ordering :: Relaxed ) {
83- return Profiler { desc : None } ;
84+ return Profiler { label : None } ;
8485 }
8586
8687 PROFILE_STACK . with ( |stack| {
@@ -93,35 +94,35 @@ pub fn profile(desc: &str) -> Profiler {
9394 } ;
9495 }
9596 if stack. starts . len ( ) > stack. filter_data . depth {
96- return Profiler { desc : None } ;
97+ return Profiler { label : None } ;
9798 }
9899 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 } ;
101102 }
102103
103104 stack. starts . push ( Instant :: now ( ) ) ;
104- Profiler { desc : Some ( desc . to_string ( ) ) }
105+ Profiler { label : Some ( label ) }
105106 } )
106107}
107108
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 ,
111112 start : Instant ,
112113 }
113114
114- impl Drop for Guard < ' _ > {
115+ impl Drop for Guard {
115116 fn drop ( & mut self ) {
116- eprintln ! ( "{}: {:?}" , self . desc , self . start. elapsed( ) )
117+ eprintln ! ( "{}: {:?}" , self . label , self . start. elapsed( ) )
117118 }
118119 }
119120
120- Guard { desc , start : Instant :: now ( ) }
121+ Guard { label , start : Instant :: now ( ) }
121122}
122123
123124pub struct Profiler {
124- desc : Option < String > ,
125+ label : Option < Label > ,
125126}
126127
127128pub struct Filter {
@@ -174,7 +175,7 @@ struct ProfileStack {
174175struct Message {
175176 level : usize ,
176177 duration : Duration ,
177- message : String ,
178+ label : Label ,
178179}
179180
180181impl ProfileStack {
@@ -200,14 +201,13 @@ thread_local!(static PROFILE_STACK: RefCell<ProfileStack> = RefCell::new(Profile
200201impl Drop for Profiler {
201202 fn drop ( & mut self ) {
202203 match self {
203- Profiler { desc : Some ( desc ) } => {
204+ Profiler { label : Some ( label ) } => {
204205 PROFILE_STACK . with ( |stack| {
205206 let mut stack = stack. borrow_mut ( ) ;
206207 let start = stack. starts . pop ( ) . unwrap ( ) ;
207208 let duration = start. elapsed ( ) ;
208209 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 } ) ;
211211 if level == 0 {
212212 let stdout = stderr ( ) ;
213213 let longer_than = stack. filter_data . longer_than ;
@@ -221,7 +221,7 @@ impl Drop for Profiler {
221221 }
222222 } ) ;
223223 }
224- Profiler { desc : None } => ( ) ,
224+ Profiler { label : None } => ( ) ,
225225 }
226226 }
227227}
@@ -244,7 +244,7 @@ fn print_for_idx(
244244) {
245245 let current = & msgs[ current_idx] ;
246246 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 )
248248 . expect ( "printing profiling info" ) ;
249249
250250 let longer_than_millis = longer_than. as_millis ( ) ;
@@ -257,7 +257,7 @@ fn print_for_idx(
257257 if child. duration . as_millis ( ) > longer_than_millis {
258258 print_for_idx ( * child_idx, children_map, msgs, longer_than, out) ;
259259 } 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 ) ) ;
261261 pair. 0 += child. duration ;
262262 pair. 1 += 1 ;
263263 }
@@ -409,9 +409,9 @@ mod tests {
409409 fn test_longer_than ( ) {
410410 let mut result = vec ! [ ] ;
411411 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" } ,
415415 ] ;
416416 print ( & msgs, Duration :: from_millis ( 0 ) , & mut result) ;
417417 // The calls to `bar` are so short that they'll be rounded to 0ms and should get collapsed
@@ -426,8 +426,8 @@ mod tests {
426426 fn test_unaccounted_for_topmost ( ) {
427427 let mut result = vec ! [ ] ;
428428 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" } ,
431431 ] ;
432432 print ( & msgs, Duration :: from_millis ( 0 ) , & mut result) ;
433433 assert_eq ! (
@@ -445,11 +445,11 @@ mod tests {
445445 fn test_unaccounted_for_multiple_levels ( ) {
446446 let mut result = vec ! [ ] ;
447447 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" } ,
453453 ] ;
454454 print ( & msgs, Duration :: from_millis ( 0 ) , & mut result) ;
455455 assert_eq ! (
0 commit comments