From 73da14d9522dfeee53cfdba7a835657a7cfb3054 Mon Sep 17 00:00:00 2001 From: Matthew Smith Date: Sat, 30 Nov 2019 18:53:43 -0600 Subject: [PATCH] add --total option. See https://github.com/brendangregg/FlameGraph/pull/14 and https://github.com/jonhoo/inferno/issues/17. The use case for this option is comparing multiple perf runs directly against one another. Specifying the # of samples to use for the total width means the individual rectangles in each graph can be directly compared to each other rather than being resized differently if one run finished more quickly than another. --- src/bin/flamegraph.rs | 5 +++++ src/flamegraph/mod.rs | 13 ++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/bin/flamegraph.rs b/src/bin/flamegraph.rs index 0d895db4..76961d98 100644 --- a/src/bin/flamegraph.rs +++ b/src/bin/flamegraph.rs @@ -173,6 +173,10 @@ struct Opt { )] title: String, + /// Set total width to this many samples + #[structopt(long = "total", value_name = "UINT")] + total: Option, + /// Width of image #[structopt(long = "width", value_name = "UINT")] width: Option, @@ -210,6 +214,7 @@ impl<'a> Opt { // set style options options.subtitle = self.subtitle; + options.total_samples = self.total; options.image_width = self.width; options.frame_height = self.height; options.min_width = self.minwidth; diff --git a/src/flamegraph/mod.rs b/src/flamegraph/mod.rs index 029202fe..19f3c5d4 100644 --- a/src/flamegraph/mod.rs +++ b/src/flamegraph/mod.rs @@ -12,6 +12,7 @@ mod merge; mod rand; mod svg; +use std::cmp; use std::fs::File; use std::io::prelude::*; use std::io::{self, BufReader}; @@ -142,6 +143,11 @@ pub struct Options<'a> { /// Defaults to None. pub subtitle: Option, + /// # of samples to size the flame graph width to + /// + /// Defaults to None, which means it will be determined by the input being charted. + pub total_samples: Option, + /// Width of the flame graph /// /// Defaults to None, which means the width will be "fluid". @@ -255,6 +261,7 @@ impl<'a> Default for Options<'a> { count_name: defaults::COUNT_NAME.to_string(), name_type: defaults::NAME_TYPE.to_string(), factor: defaults::FACTOR, + total_samples: Default::default(), image_width: Default::default(), notes: Default::default(), subtitle: Default::default(), @@ -408,8 +415,12 @@ where ))); } + let timemax = cmp::max(opt.total_samples.unwrap_or(time), time); + if opt.total_samples.unwrap_or(time) < time { + warn!("Specified --total {} is less than actual total {}, so ignored", opt.total_samples.unwrap(), time); + } + let image_width = opt.image_width.unwrap_or(DEFAULT_IMAGE_WIDTH) as f64; - let timemax = time; let widthpertime_pct = 100.0 / timemax as f64; let minwidth_time = opt.min_width / widthpertime_pct;