use HashMap instead of vector for profiler buckets

This commit is contained in:
Tim Kuehn 2013-08-28 18:37:34 -04:00
parent 048a39d4a5
commit 47ec798b92

View file

@ -8,6 +8,7 @@ use std::cell::Cell;
use std::comm::{Port, SharedChan}; use std::comm::{Port, SharedChan};
use extra::sort::tim_sort; use extra::sort::tim_sort;
use std::iterator::AdditiveIterator; use std::iterator::AdditiveIterator;
use std::hashmap::HashMap;
// front-end representation of the profiler used to communicate with the profiler // front-end representation of the profiler used to communicate with the profiler
#[deriving(Clone)] #[deriving(Clone)]
@ -26,7 +27,14 @@ impl ProfilerChan {
} }
} }
#[deriving(Eq, Clone)] pub enum ProfilerMsg {
// Normal message used for reporting time
TimeMsg(ProfilerCategory, float),
// Message used to force print the profiling metrics
PrintMsg,
}
#[deriving(Eq, Clone, IterBytes)]
pub enum ProfilerCategory { pub enum ProfilerCategory {
CompositingCategory, CompositingCategory,
LayoutQueryCategory, LayoutQueryCategory,
@ -44,27 +52,7 @@ pub enum ProfilerCategory {
// FIXME(rust#8803): workaround for lack of CTFE function on enum types to return length // FIXME(rust#8803): workaround for lack of CTFE function on enum types to return length
NumBuckets, NumBuckets,
} }
struct ProfilerBucket { type ProfilerBuckets = HashMap<ProfilerCategory, ~[float]>;
category: ProfilerCategory,
data: ~[float],
}
impl ProfilerBucket {
fn new(category: ProfilerCategory) -> ProfilerBucket {
ProfilerBucket {
category: category,
data: ~[],
}
}
}
// FIXME(rust#5873) this should be initialized by a NumBuckets cast
type ProfilerBuckets = [ProfilerBucket, ..13];
pub enum ProfilerMsg {
// Normal message used for reporting time
TimeMsg(ProfilerCategory, float),
// Message used to force print the profiling metrics
PrintMsg,
}
// back end of the profiler that handles data aggregation and performance metrics // back end of the profiler that handles data aggregation and performance metrics
pub struct Profiler { pub struct Profiler {
@ -81,21 +69,22 @@ impl ProfilerCategory {
// enumeration of all ProfilerCategory types // enumeration of all ProfilerCategory types
fn empty_buckets() -> ProfilerBuckets { fn empty_buckets() -> ProfilerBuckets {
[ let mut buckets = HashMap::with_capacity(NumBuckets as uint);
ProfilerBucket::new(CompositingCategory), buckets.insert(CompositingCategory, ~[]);
ProfilerBucket::new(LayoutQueryCategory), buckets.insert(LayoutQueryCategory, ~[]);
ProfilerBucket::new(LayoutPerformCategory), buckets.insert(LayoutPerformCategory, ~[]);
ProfilerBucket::new(LayoutAuxInitCategory), buckets.insert(LayoutAuxInitCategory, ~[]);
ProfilerBucket::new(LayoutSelectorMatchCategory), buckets.insert(LayoutSelectorMatchCategory, ~[]);
ProfilerBucket::new(LayoutTreeBuilderCategory), buckets.insert(LayoutTreeBuilderCategory, ~[]);
ProfilerBucket::new(LayoutMainCategory), buckets.insert(LayoutMainCategory, ~[]);
ProfilerBucket::new(LayoutShapingCategory), buckets.insert(LayoutShapingCategory, ~[]);
ProfilerBucket::new(LayoutDispListBuildCategory), buckets.insert(LayoutDispListBuildCategory, ~[]);
ProfilerBucket::new(GfxRegenAvailableFontsCategory), buckets.insert(GfxRegenAvailableFontsCategory, ~[]);
ProfilerBucket::new(RenderingDrawingCategory), buckets.insert(RenderingDrawingCategory, ~[]);
ProfilerBucket::new(RenderingPrepBuffCategory), buckets.insert(RenderingPrepBuffCategory, ~[]);
ProfilerBucket::new(RenderingCategory), buckets.insert(RenderingCategory, ~[]);
]
buckets
} }
// some categories are subcategories of LayoutPerformCategory // some categories are subcategories of LayoutPerformCategory
@ -139,7 +128,7 @@ impl Profiler {
fn handle_msg(&mut self, msg: ProfilerMsg) { fn handle_msg(&mut self, msg: ProfilerMsg) {
match msg { match msg {
TimeMsg(category, t) => self.buckets[category as uint].data.push(t), TimeMsg(category, t) => self.buckets.get_mut(&category).push(t),
PrintMsg => match self.last_msg { PrintMsg => match self.last_msg {
// only print if more data has arrived since the last printout // only print if more data has arrived since the last printout
Some(TimeMsg(*)) => self.print_buckets(), Some(TimeMsg(*)) => self.print_buckets(),
@ -153,7 +142,7 @@ impl Profiler {
println(fmt!("%31s %15s %15s %15s %15s %15s", println(fmt!("%31s %15s %15s %15s %15s %15s",
"_category_", "_mean (ms)_", "_median (ms)_", "_category_", "_mean (ms)_", "_median (ms)_",
"_min (ms)_", "_max (ms)_", "_bucket size_")); "_min (ms)_", "_max (ms)_", "_bucket size_"));
for &ProfilerBucket { category: ref category, data: ref mut data } in self.buckets.mut_iter() { for (category, data) in self.buckets.mut_iter() {
tim_sort(*data); tim_sort(*data);
let data_len = data.len(); let data_len = data.len();
if data_len > 0 { if data_len > 0 {
@ -200,8 +189,6 @@ mod test {
#[test] #[test]
fn check_order() { fn check_order() {
let buckets = ProfilerCategory::empty_buckets(); let buckets = ProfilerCategory::empty_buckets();
for (i, bucket) in buckets.iter().enumerate() { assert!(buckets.len() == NumBuckets as uint);
assert!(bucket.category as uint == i);
}
} }
} }