aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src/display/meter.rs
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty/src/display/meter.rs')
-rw-r--r--alacritty/src/display/meter.rs97
1 files changed, 97 insertions, 0 deletions
diff --git a/alacritty/src/display/meter.rs b/alacritty/src/display/meter.rs
new file mode 100644
index 00000000..c07d901f
--- /dev/null
+++ b/alacritty/src/display/meter.rs
@@ -0,0 +1,97 @@
+//! Rendering time meter.
+//!
+//! Used to track rendering times and provide moving averages.
+//!
+//! # Examples
+//!
+//! ```rust
+//! // create a meter
+//! let mut meter = alacritty_terminal::meter::Meter::new();
+//!
+//! // Sample something.
+//! {
+//! let _sampler = meter.sampler();
+//! }
+//!
+//! // Get the moving average. The meter tracks a fixed number of samples, and
+//! // the average won't mean much until it's filled up at least once.
+//! println!("Average time: {}", meter.average());
+//! ```
+
+use std::time::{Duration, Instant};
+
+const NUM_SAMPLES: usize = 10;
+
+/// The meter.
+#[derive(Default)]
+pub struct Meter {
+ /// Track last 60 timestamps.
+ times: [f64; NUM_SAMPLES],
+
+ /// Average sample time in microseconds.
+ avg: f64,
+
+ /// Index of next time to update..
+ index: usize,
+}
+
+/// Sampler.
+///
+/// Samplers record how long they are "alive" for and update the meter on drop..
+pub struct Sampler<'a> {
+ /// Reference to meter that created the sampler.
+ meter: &'a mut Meter,
+
+ /// When the sampler was created.
+ created_at: Instant,
+}
+
+impl<'a> Sampler<'a> {
+ fn new(meter: &'a mut Meter) -> Sampler<'a> {
+ Sampler { meter, created_at: Instant::now() }
+ }
+
+ #[inline]
+ fn alive_duration(&self) -> Duration {
+ self.created_at.elapsed()
+ }
+}
+
+impl<'a> Drop for Sampler<'a> {
+ fn drop(&mut self) {
+ self.meter.add_sample(self.alive_duration());
+ }
+}
+
+impl Meter {
+ /// Create a meter.
+ pub fn new() -> Meter {
+ Default::default()
+ }
+
+ /// Get a sampler.
+ pub fn sampler(&mut self) -> Sampler<'_> {
+ Sampler::new(self)
+ }
+
+ /// Get the current average sample duration in microseconds.
+ pub fn average(&self) -> f64 {
+ self.avg
+ }
+
+ /// Add a sample.
+ ///
+ /// Used by Sampler::drop.
+ fn add_sample(&mut self, sample: Duration) {
+ let mut usec = 0f64;
+
+ usec += f64::from(sample.subsec_nanos()) / 1e3;
+ usec += (sample.as_secs() as f64) * 1e6;
+
+ let prev = self.times[self.index];
+ self.times[self.index] = usec;
+ self.avg -= prev / NUM_SAMPLES as f64;
+ self.avg += usec / NUM_SAMPLES as f64;
+ self.index = (self.index + 1) % NUM_SAMPLES;
+ }
+}