diff options
| author | Mica White <botahamec@outlook.com> | 2024-08-15 20:23:26 -0400 |
|---|---|---|
| committer | Mica White <botahamec@outlook.com> | 2024-08-25 19:24:37 -0400 |
| commit | 509e5ce1e17417a70b9bcce8bc6e33c05106811d (patch) | |
| tree | 5b1fe60a65b5f42a90023ead03c32336033afa1f /profiler/src/lib.rs | |
| parent | db9aa9f1bf49e8bede384b9ceb1e1fb82b522799 (diff) | |
Start profiling
Diffstat (limited to 'profiler/src/lib.rs')
| -rw-r--r-- | profiler/src/lib.rs | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/profiler/src/lib.rs b/profiler/src/lib.rs new file mode 100644 index 0000000..d23ad24 --- /dev/null +++ b/profiler/src/lib.rs @@ -0,0 +1,103 @@ +use std::sync::OnceLock; + +use alligator_console::{ConsoleLogger, ConsoleMessage}; +use chrono::{DateTime, Utc}; +use scopeguard::ScopeGuard; + +static GLOBAL_PROFILER: OnceLock<Profiler> = OnceLock::new(); + +struct Profiler { + logger: ConsoleLogger, + start_time: DateTime<Utc>, +} + +impl Profiler { + fn new(logger: ConsoleLogger) -> Self { + Self { + logger, + start_time: Utc::now(), + } + } + + fn current_timestamp(&self) -> i64 { + Utc::now() + .signed_duration_since(DateTime::UNIX_EPOCH) + .num_microseconds() + .unwrap_or(i64::MAX) + } + + fn finish_frame(&self) { + self.logger.send(ConsoleMessage::FrameTime { + timestamp: self.current_timestamp(), + }) + } + + fn start_scope(&self, scope_name: String) { + self.logger.send(ConsoleMessage::ScopeStart { + scope_name, + timestamp: self.current_timestamp(), + }) + } + + fn end_scope(&self) { + self.logger.send(ConsoleMessage::ScopeEnd { + timestamp: self.current_timestamp(), + }) + } +} + +pub fn set_profiler(logger: ConsoleLogger) { + GLOBAL_PROFILER.get_or_init(|| Profiler::new(logger)); +} + +pub fn finish_frame() { + GLOBAL_PROFILER.get().unwrap().finish_frame(); +} + +pub fn start_scope(scope_name: impl AsRef<str>) { + GLOBAL_PROFILER + .get() + .unwrap() + .start_scope(scope_name.as_ref().to_string()); +} + +pub fn end_scope() { + GLOBAL_PROFILER.get().unwrap().end_scope(); +} + +pub fn profile_scope(scope_name: impl AsRef<str>) -> ScopeGuard<(), impl FnOnce(())> { + start_scope(scope_name); + scopeguard::guard((), |_| end_scope()) +} + +#[macro_export] +macro_rules! scope { + ($scope_name: expr) => { + let _profiling_scope = $crate::profile_scope($scope_name); + }; + () => { + let _profiling_scope = $crate::profile_scope("unnamed scope"); + }; +} + +#[macro_export] +macro_rules! function_name { + () => {{ + fn f() {} + fn type_name_of<T>(_: T) -> &'static str { + std::any::type_name::<T>() + } + type_name_of(f) + .split("::") + .filter(|&part| part != "f") + .collect::<Vec<&str>>() + .join("::") + }}; +} + +#[macro_export] +macro_rules! profile_function { + () => { + $crate::scope!($crate::function_name!()); + }; +} |
