mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
Simplify profiler impl (bubble up Option and shorten code
This commit is contained in:
parent
fe99a29ad1
commit
24d18d92f6
1 changed files with 21 additions and 24 deletions
|
@ -30,8 +30,9 @@ pub fn init_from(spec: &str) {
|
||||||
pub type Label = &'static str;
|
pub type Label = &'static str;
|
||||||
|
|
||||||
/// This function starts a profiling scope in the current execution stack with a given description.
|
/// 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 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 invoked multiple times at the execution stack. In this case the profiling information will be nested at the output.
|
/// 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.
|
/// Profiling information is being printed in the stderr.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
|
@ -58,36 +59,35 @@ pub type Label = &'static str;
|
||||||
/// ```
|
/// ```
|
||||||
pub fn profile(label: Label) -> Profiler {
|
pub fn profile(label: Label) -> Profiler {
|
||||||
assert!(!label.is_empty());
|
assert!(!label.is_empty());
|
||||||
let enabled = PROFILING_ENABLED.load(Ordering::Relaxed)
|
|
||||||
&& PROFILE_STACK.with(|stack| stack.borrow_mut().push(label));
|
if PROFILING_ENABLED.load(Ordering::Relaxed)
|
||||||
let label = if enabled { Some(label) } else { None };
|
&& PROFILE_STACK.with(|stack| stack.borrow_mut().push(label))
|
||||||
Profiler { label, detail: None }
|
{
|
||||||
|
Profiler(Some(ProfilerImpl { label, detail: None }))
|
||||||
|
} else {
|
||||||
|
Profiler(None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Profiler {
|
pub struct Profiler(Option<ProfilerImpl>);
|
||||||
label: Option<Label>,
|
|
||||||
|
struct ProfilerImpl {
|
||||||
|
label: Label,
|
||||||
detail: Option<String>,
|
detail: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Profiler {
|
impl Profiler {
|
||||||
pub fn detail(mut self, detail: impl FnOnce() -> String) -> Profiler {
|
pub fn detail(mut self, detail: impl FnOnce() -> String) -> Profiler {
|
||||||
if self.label.is_some() {
|
if let Some(profiler) = &mut self.0 {
|
||||||
self.detail = Some(detail())
|
profiler.detail = Some(detail())
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Profiler {
|
impl Drop for ProfilerImpl {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
match self {
|
PROFILE_STACK.with(|it| it.borrow_mut().pop(self.label, self.detail.take()));
|
||||||
Profiler { label: Some(label), detail } => {
|
|
||||||
PROFILE_STACK.with(|stack| {
|
|
||||||
stack.borrow_mut().pop(label, detail.take());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Profiler { label: None, .. } => (),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,21 +179,18 @@ impl ProfileStack {
|
||||||
pub fn pop(&mut self, label: Label, detail: Option<String>) {
|
pub fn pop(&mut self, label: Label, detail: Option<String>) {
|
||||||
let start = self.starts.pop().unwrap();
|
let start = self.starts.pop().unwrap();
|
||||||
let duration = start.elapsed();
|
let duration = start.elapsed();
|
||||||
let level = self.starts.len();
|
|
||||||
self.messages.finish(Message { duration, label, detail });
|
self.messages.finish(Message { duration, label, detail });
|
||||||
if level == 0 {
|
if self.starts.is_empty() {
|
||||||
let longer_than = self.filter.longer_than;
|
let longer_than = self.filter.longer_than;
|
||||||
// Convert to millis for comparison to avoid problems with rounding
|
// Convert to millis for comparison to avoid problems with rounding
|
||||||
// (otherwise we could print `0ms` despite user's `>0` filter when
|
// (otherwise we could print `0ms` despite user's `>0` filter when
|
||||||
// `duration` is just a few nanos).
|
// `duration` is just a few nanos).
|
||||||
if duration.as_millis() > longer_than.as_millis() {
|
if duration.as_millis() > longer_than.as_millis() {
|
||||||
let stderr = stderr();
|
|
||||||
if let Some(root) = self.messages.root() {
|
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();
|
self.messages.clear();
|
||||||
assert!(self.starts.is_empty())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue