From 9f6cbf91c60c9609453ceba87a65cf438b565893 Mon Sep 17 00:00:00 2001 From: Tim Kuehn Date: Wed, 3 Jul 2013 20:27:36 -0700 Subject: [PATCH] mildly cleaner profiling code in util::time --- src/components/gfx/opts.rs | 13 ++--- src/components/gfx/render_task.rs | 4 +- src/components/main/servo.rc | 2 +- src/components/util/time.rs | 87 +++++++++++++++---------------- 4 files changed, 53 insertions(+), 53 deletions(-) diff --git a/src/components/gfx/opts.rs b/src/components/gfx/opts.rs index 2d0d7dfecac..431382d26f0 100644 --- a/src/components/gfx/opts.rs +++ b/src/components/gfx/opts.rs @@ -8,7 +8,7 @@ use azure::azure_hl::{BackendType, CairoBackend, CoreGraphicsBackend}; use azure::azure_hl::{CoreGraphicsAcceleratedBackend, Direct2DBackend, SkiaBackend}; -use std::f64; +use std::float; use std::result; use std::uint; @@ -17,7 +17,7 @@ pub struct Opts { render_backend: BackendType, n_render_threads: uint, tile_size: uint, - profiler_period: Option, + profiler_period: Option, /// A scale factor to apply to tiles, to allow rendering tiles at higher resolutions for /// testing pan and zoom code. @@ -40,9 +40,10 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts { ]; let opt_match = match getopts::getopts(args, opts) { - result::Ok(m) => { copy m } - result::Err(f) => { fail!(getopts::fail_str(copy f)) } + result::Ok(m) => m, + result::Err(f) => fail!(getopts::fail_str(copy f)), }; + let urls = if opt_match.free.is_empty() { fail!(~"servo asks that you provide 1 or more URLs") } else { @@ -82,10 +83,10 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts { None => 1, // FIXME: Number of cores. }; - let profiler_period: Option = + let profiler_period: Option = // if only flag is present, default to 5 second period match getopts::opt_default(&opt_match, "p", "5") { - Some(period) => Some(f64::from_str(period).get()), + Some(period) => Some(float::from_str(period).get()), None => None, }; diff --git a/src/components/gfx/render_task.rs b/src/components/gfx/render_task.rs index d704c2e8160..05cbd0bc079 100644 --- a/src/components/gfx/render_task.rs +++ b/src/components/gfx/render_task.rs @@ -128,8 +128,8 @@ impl RenderTask { PaintPermissionGranted => { self.paint_permission = true; match self.last_paint_msg { - Some((ref layer_buffer_set, ref layer_size)) => { - self.compositor.paint(self.id, layer_buffer_set.clone(), *layer_size); + Some((ref layer_buffer_set, layer_size)) => { + self.compositor.paint(self.id, layer_buffer_set.clone(), layer_size); self.compositor.set_render_state(IdleRenderState); } None => {} diff --git a/src/components/main/servo.rc b/src/components/main/servo.rc index 10986322516..9841b096134 100755 --- a/src/components/main/servo.rc +++ b/src/components/main/servo.rc @@ -109,7 +109,7 @@ fn run(opts: &Opts) { do spawn { loop { extra::timer::sleep(&uv_global_loop::get(), - (period * 1000f64) as uint); + (period * 1000f) as uint); profiler_chan.send(PrintMsg); } } diff --git a/src/components/util/time.rs b/src/components/util/time.rs index b8c88753974..34de480b99c 100644 --- a/src/components/util/time.rs +++ b/src/components/util/time.rs @@ -45,10 +45,11 @@ pub enum ProfilerCategory { } // FIXME(#5873) this should be initialized by a NUM_BUCKETS cast, static BUCKETS: uint = 13; +type ProfilerBuckets = [(ProfilerCategory, ~[float]), ..BUCKETS]; pub enum ProfilerMsg { // Normal message used for reporting time - TimeMsg(ProfilerCategory, f64), + TimeMsg(ProfilerCategory, float), // Message used to force print the profiling metrics PrintMsg, } @@ -56,7 +57,7 @@ pub enum ProfilerMsg { // back end of the profiler that handles data aggregation and performance metrics pub struct Profiler { port: Port, - buckets: ~[(ProfilerCategory, ~[f64])], + buckets: ProfilerBuckets, last_msg: Option, } @@ -67,29 +68,30 @@ impl ProfilerCategory { } // enumeration of all ProfilerCategory types - // FIXME(tkuehn): this is ugly and error-prone, - // but currently we lack better alternatives without an enum enumeration - priv fn empty_buckets() -> ~[(ProfilerCategory, ~[f64])] { - let mut vec = ~[]; - vec.push((CompositingCategory, ~[])); - vec.push((LayoutQueryCategory, ~[])); - vec.push((LayoutPerformCategory, ~[])); - vec.push((LayoutAuxInitCategory, ~[])); - vec.push((LayoutSelectorMatchCategory, ~[])); - vec.push((LayoutTreeBuilderCategory, ~[])); - vec.push((LayoutMainCategory, ~[])); - vec.push((LayoutShapingCategory, ~[])); - vec.push((LayoutDispListBuildCategory, ~[])); - vec.push((GfxRegenAvailableFontsCategory, ~[])); - vec.push((RenderingDrawingCategory, ~[])); - vec.push((RenderingPrepBuffCategory, ~[])); - vec.push((RenderingCategory, ~[])); + // TODO(tkuehn): is there a better way to ensure proper order of categories? + priv fn empty_buckets() -> ProfilerBuckets { + let buckets = [ + (CompositingCategory, ~[]), + (LayoutQueryCategory, ~[]), + (LayoutPerformCategory, ~[]), + (LayoutAuxInitCategory, ~[]), + (LayoutSelectorMatchCategory, ~[]), + (LayoutTreeBuilderCategory, ~[]), + (LayoutMainCategory, ~[]), + (LayoutShapingCategory, ~[]), + (LayoutDispListBuildCategory, ~[]), + (GfxRegenAvailableFontsCategory, ~[]), + (RenderingDrawingCategory, ~[]), + (RenderingPrepBuffCategory, ~[]), + (RenderingCategory, ~[]), + ]; - ProfilerCategory::check_order(vec); - vec + ProfilerCategory::check_order(&buckets); + buckets } - priv fn check_order(vec: &[(ProfilerCategory, ~[f64])]) { + // ensure that the order of the buckets matches the order of the enum categories + priv fn check_order(vec: &ProfilerBuckets) { for vec.iter().advance |&(category, _)| { if category != vec[category as uint].first() { fail!("Enum category does not match bucket index. This is a bug."); @@ -136,13 +138,11 @@ impl Profiler { priv fn handle_msg(&mut self, msg: ProfilerMsg) { match msg { TimeMsg(category, t) => match self.buckets[category as uint] { - // FIXME(#3874): this should be a let (cat, ref mut bucket) = ..., - // not a match - (_, ref mut data) => { - data.push(t); - } + //TODO(tkuehn): would be nice to have tuple.second_mut() + (_, ref mut data) => data.push(t), }, PrintMsg => match self.last_msg { + // only print if more data has arrived since the last printout Some(TimeMsg(*)) => self.print_buckets(), _ => {} }, @@ -155,20 +155,19 @@ impl Profiler { "_category_", "_mean (ms)_", "_median (ms)_", "_min (ms)_", "_max (ms)_", "_bucket size_")); for self.buckets.mut_iter().advance |bucket| { - match *bucket { - (category, ref mut data) => { - tim_sort(*data); - let data_len = data.len(); - if data_len > 0 { - let (mean, median, min, max) = - (data.iter().fold(0f64, |a, b| a + *b) / (data_len as f64), - data[data_len / 2], - data.iter().min(), - data.iter().max()); - println(fmt!("%-30s: %15.4? %15.4? %15.4? %15.4? %15u", - category.format(), mean, median, min, max, data_len)); - } - } + let (category, data) = match *bucket { + (category, ref mut data) => (category, data), + }; + tim_sort(*data); + let data_len = data.len(); + if data_len > 0 { + let (mean, median, &min, &max) = + (data.iter().fold(0f, |a, b| a + *b) / (data_len as float), + data[data_len / 2], + data.iter().min().unwrap(), + data.iter().max().unwrap()); + println(fmt!("%-30s: %15.4f %15.4f %15.4f %15.4f %15u", + category.format(), mean, median, min, max, data_len)); } } println(""); @@ -183,7 +182,7 @@ pub fn profile(category: ProfilerCategory, let start_time = precise_time_ns(); let val = callback(); let end_time = precise_time_ns(); - let ms = ((end_time - start_time) as f64 / 1000000f64); + let ms = ((end_time - start_time) as float / 1000000f); profiler_chan.send(TimeMsg(category, ms)); return val; } @@ -192,8 +191,8 @@ pub fn time(msg: &str, callback: &fn() -> T) -> T{ let start_time = precise_time_ns(); let val = callback(); let end_time = precise_time_ns(); - let ms = ((end_time - start_time) as f64 / 1000000f64); - if ms >= 5f64 { + let ms = ((end_time - start_time) as float / 1000000f); + if ms >= 5f { debug!("%s took %? ms", msg, ms); } return val;