mirror of
https://github.com/alacritty/alacritty.git
synced 2024-11-11 13:51:01 -05:00
105 lines
2.3 KiB
Rust
105 lines
2.3 KiB
Rust
|
//! Rendering time meter
|
||
|
//!
|
||
|
//! Used to track rendering times and provide moving averages.
|
||
|
//!
|
||
|
//! # Examples
|
||
|
//!
|
||
|
//! ```rust
|
||
|
//! // create a meter
|
||
|
//! let mut meter = Meter::new();
|
||
|
//!
|
||
|
//! // Sample something.
|
||
|
//! {
|
||
|
//! let _sampler = meter.sampler();
|
||
|
//! }
|
||
|
//!
|
||
|
//! // Get the moving average. The meter tracks a fixed number of samles, and the average won't mean
|
||
|
//! // much until it's filled up at least once.
|
||
|
//! printf!("Average time: {}", meter.average());
|
||
|
|
||
|
use std::time::{Instant, Duration};
|
||
|
|
||
|
const NUM_SAMPLES: usize = 60;
|
||
|
|
||
|
/// The meter
|
||
|
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: 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) {
|
||
|
// Work around borrowck
|
||
|
let duration = self.alive_duration();
|
||
|
self.meter.add_sample(duration);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl Meter {
|
||
|
/// Create a meter
|
||
|
pub fn new() -> Meter {
|
||
|
Meter {
|
||
|
times: [0.0; NUM_SAMPLES],
|
||
|
avg: 0.0,
|
||
|
index: 0,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// 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 += (sample.subsec_nanos() as f64) / 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;
|
||
|
}
|
||
|
}
|