From 509e5ce1e17417a70b9bcce8bc6e33c05106811d Mon Sep 17 00:00:00 2001 From: Mica White Date: Thu, 15 Aug 2024 20:23:26 -0400 Subject: Start profiling --- profiler/Cargo.toml | 10 +++++ profiler/src/lib.rs | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 profiler/Cargo.toml create mode 100644 profiler/src/lib.rs (limited to 'profiler') diff --git a/profiler/Cargo.toml b/profiler/Cargo.toml new file mode 100644 index 0000000..d9c7f2b --- /dev/null +++ b/profiler/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "alligator_profiler" +version = "0.1.0" +edition = "2021" + +[dependencies] +alligator_console = { path = "../console" } + +scopeguard = "1" +chrono = "0.4" \ No newline at end of file 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 = OnceLock::new(); + +struct Profiler { + logger: ConsoleLogger, + start_time: DateTime, +} + +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) { + 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) -> 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) -> &'static str { + std::any::type_name::() + } + type_name_of(f) + .split("::") + .filter(|&part| part != "f") + .collect::>() + .join("::") + }}; +} + +#[macro_export] +macro_rules! profile_function { + () => { + $crate::scope!($crate::function_name!()); + }; +} -- cgit v1.2.3