tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

profiler.rs (2932B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 use std::collections::VecDeque;
      6 
      7 #[derive(Debug)]
      8 pub struct GraphStats {
      9    pub min: f64,
     10    pub avg: f64,
     11    pub max: f64,
     12    pub sum: f64,
     13    pub samples: usize,
     14 }
     15 
     16 pub struct Graph {
     17    pub name: String,
     18    pub values: VecDeque<f64>,
     19 }
     20 
     21 impl Graph {
     22    pub fn new(name: &str, max_samples: usize) -> Self {
     23        let mut values = VecDeque::new();
     24        values.reserve(max_samples);
     25 
     26        Graph {
     27            name: name.into(),
     28            values
     29        }
     30    }
     31 
     32    pub fn push(&mut self, val: f64) {
     33        if self.values.len() == self.values.capacity() {
     34            self.values.pop_back();
     35        }
     36        self.values.push_front(val);
     37    }
     38 
     39    pub fn stats(&self) -> GraphStats {
     40        let mut stats = GraphStats {
     41            min: f64::MAX,
     42            avg: 0.0,
     43            max: -f64::MAX,
     44            sum: 0.0,
     45            samples: 0,
     46        };
     47 
     48        let mut samples = 0;
     49        for value in &self.values {
     50            if value.is_finite() {
     51                stats.min = stats.min.min(*value);
     52                stats.max = stats.max.max(*value);
     53                stats.sum += *value;
     54                samples += 1;
     55            }
     56        }
     57 
     58        if samples > 0 {
     59            stats.avg = stats.sum / samples as f64;
     60            stats.samples = samples;
     61        } else {
     62            stats.min = 0.0;
     63            stats.max = 0.0;
     64        }
     65 
     66        stats
     67    }
     68 }
     69 
     70 pub fn ui(app: &mut super::Gui, ui: &mut egui::Ui) {
     71    for graph in app.data_model.profile_graphs.values() {
     72        let stats = graph.stats();
     73 
     74        ui.label(&graph.name);
     75 
     76        let (response, painter) = ui.allocate_painter(
     77            egui::vec2(1024.0, 128.0),
     78            egui::Sense::hover(),
     79        );
     80 
     81        let rect = response.rect;
     82 
     83        // Background
     84        painter.rect_filled(rect, 0.0, egui::Color32::from_rgb(77, 77, 77));
     85 
     86        let max_samples = graph.values.capacity() as f32;
     87        let w = rect.width() / max_samples;
     88        let h = rect.height();
     89 
     90        let color_t0 = egui::Color32::from_rgb(0, 255, 0);
     91 
     92        for (index, sample) in graph.values.iter().enumerate() {
     93            if !sample.is_finite() {
     94                continue;
     95            }
     96            let sample = *sample as f32;
     97            let x1 = rect.right() - index as f32 * w;
     98            let x0 = x1 - w;
     99 
    100            let y0 = rect.bottom() - (sample / stats.max as f32) * h;
    101            let y1 = rect.bottom();
    102 
    103            let rect = egui::Rect::from_min_max(
    104                egui::pos2(x0, y0),
    105                egui::pos2(x1, y1),
    106            );
    107 
    108            painter.rect_filled(rect, 0.0, color_t0);
    109        }
    110 
    111        ui.label(format!("Min: {:.2}, Avg: {:.2}, Max: {:.2}", stats.min, stats.avg, stats.max));
    112    }
    113 }