2016-06-29 23:56:12 -04:00
|
|
|
// Copyright 2016 Joe Wilm, The Alacritty Project Contributors
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
//
|
2016-05-21 14:08:50 -04:00
|
|
|
//! Rendering time meter
|
|
|
|
//!
|
|
|
|
//! Used to track rendering times and provide moving averages.
|
|
|
|
//!
|
|
|
|
//! # Examples
|
|
|
|
//!
|
|
|
|
//! ```rust
|
|
|
|
//! // create a meter
|
2016-11-19 19:16:20 -05:00
|
|
|
//! let mut meter = alacritty::meter::Meter::new();
|
2016-05-21 14:08:50 -04:00
|
|
|
//!
|
|
|
|
//! // Sample something.
|
|
|
|
//! {
|
|
|
|
//! let _sampler = meter.sampler();
|
|
|
|
//! }
|
|
|
|
//!
|
2016-12-17 01:48:04 -05:00
|
|
|
//! // 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.
|
2016-11-19 19:16:20 -05:00
|
|
|
//! println!("Average time: {}", meter.average());
|
2016-05-21 14:08:50 -04:00
|
|
|
|
|
|
|
use std::time::{Instant, Duration};
|
|
|
|
|
2016-11-28 17:13:11 -05:00
|
|
|
const NUM_SAMPLES: usize = 10;
|
2016-05-21 14:08:50 -04:00
|
|
|
|
|
|
|
/// The meter
|
2016-12-17 01:13:51 -05:00
|
|
|
#[derive(Default)]
|
2016-05-21 14:08:50 -04:00
|
|
|
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 {
|
2016-12-17 01:13:51 -05:00
|
|
|
Default::default()
|
2016-05-21 14:08:50 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/// 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;
|
|
|
|
}
|
|
|
|
}
|