From 24d18d92f69c1ce3d4fc3ff3be67d4f9bf65d857 Mon Sep 17 00:00:00 2001 From: veetaha <veetaha2@gmail.com> Date: Sun, 26 Apr 2020 00:10:44 +0300 Subject: [PATCH] Simplify profiler impl (bubble up Option and shorten code --- crates/ra_prof/src/hprof.rs | 45 +++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/crates/ra_prof/src/hprof.rs b/crates/ra_prof/src/hprof.rs index 2b8a903636c..a3f5321fb3c 100644 --- a/crates/ra_prof/src/hprof.rs +++ b/crates/ra_prof/src/hprof.rs @@ -30,8 +30,9 @@ pub fn init_from(spec: &str) { pub type Label = &'static str; /// This function starts a profiling scope in the current execution stack with a given description. -/// It returns a Profile structure and measure elapsed time between this method invocation and Profile structure drop. -/// 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. +/// It returns a `Profile` struct that measures elapsed time between this method invocation and `Profile` struct drop. +/// It supports nested profiling scopes in case when this function is invoked multiple times at the execution stack. +/// In this case the profiling information will be nested at the output. /// Profiling information is being printed in the stderr. /// /// # Example @@ -58,36 +59,35 @@ pub type Label = &'static str; /// ``` pub fn profile(label: Label) -> Profiler { assert!(!label.is_empty()); - let enabled = PROFILING_ENABLED.load(Ordering::Relaxed) - && PROFILE_STACK.with(|stack| stack.borrow_mut().push(label)); - let label = if enabled { Some(label) } else { None }; - Profiler { label, detail: None } + + if PROFILING_ENABLED.load(Ordering::Relaxed) + && PROFILE_STACK.with(|stack| stack.borrow_mut().push(label)) + { + Profiler(Some(ProfilerImpl { label, detail: None })) + } else { + Profiler(None) + } } -pub struct Profiler { - label: Option<Label>, +pub struct Profiler(Option<ProfilerImpl>); + +struct ProfilerImpl { + label: Label, detail: Option<String>, } impl Profiler { pub fn detail(mut self, detail: impl FnOnce() -> String) -> Profiler { - if self.label.is_some() { - self.detail = Some(detail()) + if let Some(profiler) = &mut self.0 { + profiler.detail = Some(detail()) } self } } -impl Drop for Profiler { +impl Drop for ProfilerImpl { fn drop(&mut self) { - match self { - Profiler { label: Some(label), detail } => { - PROFILE_STACK.with(|stack| { - stack.borrow_mut().pop(label, detail.take()); - }); - } - Profiler { label: None, .. } => (), - } + PROFILE_STACK.with(|it| it.borrow_mut().pop(self.label, self.detail.take())); } } @@ -179,21 +179,18 @@ impl ProfileStack { pub fn pop(&mut self, label: Label, detail: Option<String>) { let start = self.starts.pop().unwrap(); let duration = start.elapsed(); - let level = self.starts.len(); self.messages.finish(Message { duration, label, detail }); - if level == 0 { + if self.starts.is_empty() { let longer_than = self.filter.longer_than; // Convert to millis for comparison to avoid problems with rounding // (otherwise we could print `0ms` despite user's `>0` filter when // `duration` is just a few nanos). if duration.as_millis() > longer_than.as_millis() { - let stderr = stderr(); if let Some(root) = self.messages.root() { - print(&self.messages, root, 0, longer_than, &mut stderr.lock()); + print(&self.messages, root, 0, longer_than, &mut stderr().lock()); } } self.messages.clear(); - assert!(self.starts.is_empty()) } } }