gloo_console/timer.rs
1//! The `console.time` and `console.timeEnd` functions allow you to log the
2//! timing of named operations to the browser's developer tools console. You
3//! call `console.time("foo")` when the operation begins, and call
4//! `console.timeEnd("foo")` when it finishes.
5//!
6//! Additionally, these measurements will show up in your browser's profiler's
7//! "timeline" or "waterfall" view.
8//!
9//! [See MDN for more info](https://developer.mozilla.org/en-US/docs/Web/API/console#Timers).
10//!
11//! This API wraps both the `time` and `timeEnd` calls into a single type
12//! named `ConsoleTimer`, ensuring both are called.
13//!
14//! ## Scoped Measurement
15//!
16//! Wrap code to be measured in a closure with [`Timer::scope`].
17//!
18//! ```no_run
19//! use gloo_console::Timer;
20//!
21//! let value = Timer::scope("foo", || {
22//! // Place code to be measured here
23//! // Optionally return a value.
24//! });
25//! ```
26//!
27//! ## RAII-Style Measurement
28//!
29//! For scenarios where [`Timer::scope`] can't be used, like with
30//! asynchronous operations, you can use `ConsoleTimer::new` to create a timer.
31//! The measurement ends when the timer object goes out of scope / is dropped.
32//!
33//! ```no_run
34//! use gloo_console::Timer;
35//! use gloo_timers::callback::Timeout;
36//!
37//! // Start timing a new operation.
38//! let timer = Timer::new("foo");
39//!
40//! // And then asynchronously finish timing.
41//! let timeout = Timeout::new(1_000, move || {
42//! drop(timer);
43//! });
44//! ```
45
46use web_sys::console;
47
48/// A console time measurement.
49///
50/// See [`Timer::scope`] for starting a labeled time measurement
51/// of code wrapped in a closure.
52#[derive(Debug)]
53pub struct Timer<'a> {
54 label: &'a str,
55}
56
57impl<'a> Timer<'a> {
58 /// Starts a console time measurement. The measurement
59 /// ends when the constructed `ConsoleTimer` object is dropped.
60 ///
61 /// # Example
62 ///
63 /// ```no_run
64 /// use gloo_console::Timer;
65 ///
66 /// let _timer = Timer::new("foo");
67 /// ```
68 pub fn new(label: &'a str) -> Timer<'a> {
69 console::time_with_label(label);
70 Timer { label }
71 }
72
73 /// Starts a scoped console time measurement
74 ///
75 /// # Example
76 ///
77 /// ```no_run
78 /// use gloo_console::Timer;
79 ///
80 /// let value = Timer::scope("foo", || {
81 /// // Code to measure here
82 /// });
83 /// ```
84 pub fn scope<F, T>(label: &str, f: F) -> T
85 where
86 F: FnOnce() -> T,
87 {
88 let _timer = Timer::new(label);
89 f()
90 }
91}
92
93impl<'a> Drop for Timer<'a> {
94 fn drop(&mut self) {
95 console::time_end_with_label(self.label);
96 }
97}