From a0a30da8ef6483880815e4eadbfd84bc41ebd517 Mon Sep 17 00:00:00 2001 From: data-pup Date: Thu, 26 Jul 2018 20:37:27 -0400 Subject: [PATCH] Add summaries to monos sub-command output. --- analyze/analyze.rs | 371 ++++++++++++------ ir/ir.rs | 3 +- twiggy/tests/expectations/cpp_monos | 3 +- twiggy/tests/expectations/monos | 102 ++--- twiggy/tests/expectations/monos_json | 2 +- twiggy/tests/expectations/monos_maxes | 16 +- twiggy/tests/expectations/monos_only_generics | 26 +- twiggy/tests/expectations/monos_wasm_csv | 8 +- 8 files changed, 339 insertions(+), 192 deletions(-) diff --git a/analyze/analyze.rs b/analyze/analyze.rs index 18afa7b1..425b6e5d 100644 --- a/analyze/analyze.rs +++ b/analyze/analyze.rs @@ -20,6 +20,7 @@ use std::cmp; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::fmt; use std::io; +use std::iter; #[derive(Debug, Clone, Copy)] enum Align { @@ -893,10 +894,10 @@ struct Monos { #[derive(Debug, PartialEq, Eq)] struct MonosEntry { - generic: String, - insts: Vec, - total: u32, - approx_potential_savings: u32, + name: String, + insts: Vec<(String, u32)>, + size: u32, + bloat: u32, } impl PartialOrd for MonosEntry { @@ -907,16 +908,55 @@ impl PartialOrd for MonosEntry { impl Ord for MonosEntry { fn cmp(&self, rhs: &MonosEntry) -> cmp::Ordering { - rhs.approx_potential_savings - .cmp(&self.approx_potential_savings) + rhs.bloat + .cmp(&self.bloat) + .then(rhs.size.cmp(&self.size)) .then(self.insts.cmp(&rhs.insts)) - .then(self.generic.cmp(&rhs.generic)) + .then(self.name.cmp(&rhs.name)) } } impl traits::Emit for Monos { #[cfg(feature = "emit_text")] fn emit_text(&self, items: &ir::Items, dest: &mut io::Write) -> Result<(), traits::Error> { + struct TableRow { + bloat: Option, + bloat_percent: Option, + size: u32, + size_percent: f64, + name: String, + }; + + // Given an entry representing a generic function and its various + // monomorphizations, return a vector of table rows. + fn process_entry<'a>( + entry: &'a MonosEntry, + total_size: f64, + ) -> impl Iterator + 'a { + let MonosEntry { + name, + insts, + size, + bloat, + } = entry; + + let get_size_percent = move |x: u32| f64::from(x) / total_size * 100.0; + + iter::once(TableRow { + bloat: Some(*bloat), + bloat_percent: Some(get_size_percent(*bloat)), + size: *size, + size_percent: get_size_percent(*size), + name: name.to_string(), + }).chain(insts.iter().map(move |(name, size)| TableRow { + bloat: None, + bloat_percent: None, + size: *size, + size_percent: get_size_percent(*size), + name: format!(" {}", name), + })) + } + let mut table = Table::with_header(vec![ (Align::Right, "Apprx. Bloat Bytes".into()), (Align::Right, "Apprx. Bloat %".into()), @@ -925,74 +965,73 @@ impl traits::Emit for Monos { (Align::Left, "Monomorphizations".to_string()), ]); - for entry in &self.monos { - let total_percent = (f64::from(entry.total)) / (f64::from(items.size())) * 100.0; - let approx_potential_savings_percent = - (f64::from(entry.approx_potential_savings)) / (f64::from(items.size())) * 100.0; + for TableRow { + bloat, + bloat_percent, + size, + size_percent, + name, + } in self + .monos + .iter() + .flat_map(|mono| process_entry(mono, f64::from(items.size()))) + { table.add_row(vec![ - entry.approx_potential_savings.to_string(), - format!("{:.2}%", approx_potential_savings_percent), - entry.total.to_string(), - format!("{:.2}%", total_percent), - entry.generic.clone(), + bloat.map(|b| b.to_string()).unwrap_or_default(), + bloat_percent + .map(|b| format!("{:.2}%", b)) + .unwrap_or_default(), + size.to_string(), + format!("{:.2}%", size_percent), + name.clone(), ]); - - for &id in &entry.insts { - let item = &items[id]; - - let size = item.size(); - let size_percent = (f64::from(size)) / (f64::from(items.size())) * 100.0; - - table.add_row(vec![ - "".into(), - "".into(), - size.to_string(), - format!("{:.2}%", size_percent), - format!(" {}", item.name()), - ]); - } } - write!(dest, "{}", &table)?; Ok(()) } #[cfg(feature = "emit_json")] fn emit_json(&self, items: &ir::Items, dest: &mut io::Write) -> Result<(), traits::Error> { - let mut arr = json::array(dest)?; - - for entry in &self.monos { - let mut obj = arr.object()?; - obj.field("generic", &entry.generic[..])?; - - obj.field( - "approximate_monomorphization_bloat_bytes", - entry.approx_potential_savings, - )?; - let approx_potential_savings_percent = - (f64::from(entry.approx_potential_savings)) / (f64::from(items.size())) * 100.0; + // Given an entry representing a generic function and its various + // monomorphizations, add its information to the given JSON object. + fn process_entry( + entry: &MonosEntry, + obj: &mut json::Object, + total_size: f64, + ) -> Result<(), traits::Error> { + let get_size_percent = |size: u32| (f64::from(size)) / total_size * 100.0; + let MonosEntry { + name, + insts, + size, + bloat, + } = entry; + obj.field("generic", name.as_str())?; + obj.field("approximate_monomorphization_bloat_bytes", *bloat)?; obj.field( "approximate_monomorphization_bloat_percent", - approx_potential_savings_percent, + get_size_percent(*bloat), )?; - - obj.field("total_size", entry.total)?; - let total_percent = (f64::from(entry.total)) / (f64::from(items.size())) * 100.0; - obj.field("total_size_percent", total_percent)?; - + obj.field("total_size", *size)?; + obj.field("total_size_percent", get_size_percent(*size))?; let mut monos = obj.array("monomorphizations")?; - for &id in &entry.insts { - let item = &items[id]; - + for (name, size, size_percent) in insts + .iter() + .map(|(name, size)| (name, size, get_size_percent(*size))) + { let mut obj = monos.object()?; - obj.field("name", item.name())?; - - let size = item.size(); - obj.field("shallow_size", size)?; - - let size_percent = (f64::from(size)) / (f64::from(items.size())) * 100.0; + obj.field("name", name.as_str())?; + obj.field("shallow_size", *size)?; obj.field("shallow_size_percent", size_percent)?; } + Ok(()) + }; + + let items_size = f64::from(items.size()); + let mut arr = json::array(dest)?; + for entry in &self.monos { + let mut obj = arr.object()?; + process_entry(entry, &mut obj, items_size)?; } Ok(()) @@ -1000,6 +1039,11 @@ impl traits::Emit for Monos { #[cfg(feature = "emit_csv")] fn emit_csv(&self, items: &ir::Items, dest: &mut io::Write) -> Result<(), traits::Error> { + // Calculate the total size of the collection of items, and define a + // helper closure to calculate a percent value for a given u32 size. + let items_size = f64::from(items.size()); + let get_size_percent = |size: u32| (f64::from(size)) / items_size * 100.0; + #[derive(Debug, Default, Serialize)] #[serde(rename_all = "PascalCase")] struct Record { @@ -1011,25 +1055,29 @@ impl traits::Emit for Monos { monomorphizations: Option, } + // Given a single `MonosEntry` object, create a record object. + let process_entry = |entry: &MonosEntry| -> Record { + let monos = entry + .insts + .iter() + .map(|(name, _)| name.as_str()) + .collect::>(); + Record { + generic: Some(entry.name.clone()), + approximate_monomorphization_bloat_bytes: Some(entry.bloat), + approximate_monomorphization_bloat_percent: Some(get_size_percent(entry.bloat)), + total_size: Some(entry.size), + total_size_percent: Some(get_size_percent(entry.size)), + monomorphizations: Some(monos.join(", ")), + } + }; + + // Create a CSV writer and iterate through the monomorphization entries. + // Process each record and pass it to the destination to be serialized. let mut wtr = csv::Writer::from_writer(dest); - let mut rc; for entry in &self.monos { - let approx_potential_savings_percent = - (f64::from(entry.approx_potential_savings)) / (f64::from(items.size())) * 100.0; - - let total_percent = (f64::from(entry.total)) / (f64::from(items.size())) * 100.0; - rc = Record { - generic: Some(entry.generic[..].to_string()), - approximate_monomorphization_bloat_bytes: Some(entry.approx_potential_savings), - approximate_monomorphization_bloat_percent: Some(approx_potential_savings_percent), - total_size: Some(entry.total), - total_size_percent: Some(total_percent), - ..Default::default() - }; - - let monos: Vec<&str> = entry.insts.iter().map(|id| items[*id].name()).collect(); - rc.monomorphizations = Some(monos.join(", ")); - wtr.serialize(rc)?; + let record = process_entry(entry); + wtr.serialize(record)?; wtr.flush()?; } Ok(()) @@ -1038,55 +1086,144 @@ impl traits::Emit for Monos { /// Find bloaty monomorphizations of generic functions. pub fn monos(items: &mut ir::Items, opts: &opt::Monos) -> Result, traits::Error> { - let mut monos = BTreeMap::new(); - for item in items.iter() { - if let Some(generic) = item.monomorphization_of() { - monos - .entry(generic) - .or_insert_with(BTreeSet::new) - .insert(item.id()); - } - } + // Type alias used to represent a map of generic function names and instantiations. + type MonosMap<'a> = BTreeMap<&'a str, Vec<(String, u32)>>; - let mut monos: Vec<_> = monos - .into_iter() - .filter_map(|(generic, insts)| { - if insts.len() <= 1 { - return None; - } + fn collect_monomorphizations<'a>(items: &'a ir::Items) -> MonosMap { + let unsorted_monos: BTreeMap<&'a str, BTreeSet<(String, u32)>> = items + .iter() + .filter_map(|item| { + if let Some(generic) = item.monomorphization_of() { + Some((generic, item)) + } else { + None + } + }).fold(BTreeMap::new(), |mut monos, (generic, inst)| { + monos + .entry(generic) + .or_insert_with(BTreeSet::new) + .insert((inst.name().to_string(), inst.size())); + monos + }); - let max = insts.iter().map(|id| items[*id].size()).max().unwrap(); - let total = insts.iter().map(|id| items[*id].size()).sum(); - let size_per_inst = total / (insts.len() as u32); - let approx_potential_savings = - cmp::min(size_per_inst * (insts.len() as u32 - 1), total - max); + unsorted_monos + .into_iter() + .map(|(generic, inst_set)| { + let mut insts = inst_set.into_iter().collect::>(); + insts.sort_by(|(a_name, a_size), (b_name, b_size)| { + b_size.cmp(a_size).then(a_name.cmp(b_name)) + }); + (generic, insts) + }).collect() + } - let generic = generic.to_string(); + // Helper function usedd to summarize a sequence of `MonosEntry` objects. + // Returns a tuple representing the number of items summarized, the total + // size of the items, and the total approximate potential savings. + fn summarize_entries<'a>(entries: impl Iterator) -> (usize, u32, u32) { + entries.fold( + (0, 0, 0), + |(total_cnt, total_size, total_savings), + MonosEntry { + insts, size, bloat, .. + }| { + ( + total_cnt + 1 + insts.len(), + total_size + size, + total_savings + bloat, + ) + }, + ) + } - let mut insts: Vec<_> = insts.into_iter().collect(); - insts.sort_by(|a, b| { - let a = &items[*a]; - let b = &items[*b]; - b.size().cmp(&a.size()) - }); - insts.truncate(if opts.only_generics() { - 0 - } else { - opts.max_monos() as usize - }); + // Helper function used to summarize a sequence of tuples representing + // instantiations of a generic function. Returns a tuple representing the + // number of instantiations found, and the total size. + fn summarize_insts<'a>(entries: impl Iterator) -> (u32, u32) { + entries.fold((0, 0), |(total_cnt, total_size), (_, size)| { + (total_cnt + 1, total_size + size) + }) + } - Some(MonosEntry { - generic, + // Find the approximate potential savings by calculating the benefits of + // removing the largest instantiation, and the benefits of removing an + // average instantiation. Returns a tuple containing total size, and bloat. + fn calculate_total_and_bloat<'a>(insts: &[(String, u32)]) -> Option<(u32, u32)> { + if let Some(max) = insts.iter().map(|(_, size)| size).max() { + let total_size = insts.iter().map(|(_, size)| size).sum::(); + let inst_cnt = insts.len() as u32; + let size_per_inst = total_size / inst_cnt; + let avg_savings = size_per_inst * (inst_cnt - 1); + let removing_largest_savings = total_size - max; + let approx_potential_savings = cmp::min(avg_savings, removing_largest_savings); + Some((total_size, approx_potential_savings)) + } else { + None + } + } + + // Process all of the monorphizations, into a vector of `MonosEntry` objects. + fn process_monomorphizations(monos_map: MonosMap, opts: &opt::Monos) -> Vec { + let mut monos = monos_map + .into_iter() + .filter_map(|(g, insts)| { + calculate_total_and_bloat(&insts).map(|(total, bloat)| (g, insts, total, bloat)) + }).map(|(g, mut insts, t, b)| { + // Truncate `insts` according to the relevant options before + // we map these values into `MonosEntry` objects. + if opts.only_generics() { + insts.truncate(0); + } else { + let max_monos = opts.max_monos() as usize; + let (rem_cnt, rem_size) = summarize_insts(insts.iter().skip(max_monos)); + insts.truncate(max_monos); + if rem_cnt > 0 { + insts.push((format!("... and {} more.", rem_cnt), rem_size)); + } + }; + (g, insts, t, b) + }).map(|(name, insts, size, bloat)| MonosEntry { + name: name.to_string(), insts, - total, - approx_potential_savings, - }) - }) - .collect(); + size, + bloat, + }).collect::>(); + monos.sort(); + monos + } + + // Collect the options that will be needed. + let max_generics = opts.max_generics() as usize; - monos.sort(); - monos.truncate(opts.max_generics() as usize); + // Collect the monomorphizations of generic functions into a map, then + // process the entries and sort the resulting vector. + let monos_map = collect_monomorphizations(&items); + let mut monos = process_monomorphizations(monos_map, &opts); + // Create an entry to represent the remaining rows that will be truncated. + let (rem_cnt, rem_size, rem_savings) = summarize_entries(monos.iter().skip(max_generics)); + let remaining = MonosEntry { + name: format!("... and {} more.", rem_cnt), + size: rem_size, + insts: vec![], + bloat: rem_savings, + }; + + // Create an entry to represent the 'total' summary. + let (total_cnt, total_size, total_savings) = summarize_entries(monos.iter()); + let total = MonosEntry { + name: format!("Σ [{} Total Rows]", total_cnt), + size: total_size, + insts: vec![], + bloat: total_savings, + }; + + // Truncate the vector, and add the 'remaining' and 'total' summary entries. + monos.truncate(max_generics); + if rem_cnt > 0 { + monos.push(remaining); + } + monos.push(total); Ok(Box::new(Monos { monos }) as Box) } diff --git a/ir/ir.rs b/ir/ir.rs index 5b067470..a0c5591f 100644 --- a/ir/ir.rs +++ b/ir/ir.rs @@ -334,8 +334,7 @@ impl Items { .expect( "Cannot call retained_sizes unless compute_retained_sizes \ has already been called", - ) - .get(&id) + ).get(&id) .cloned() .unwrap() } diff --git a/twiggy/tests/expectations/cpp_monos b/twiggy/tests/expectations/cpp_monos index d1493200..7e485f81 100644 --- a/twiggy/tests/expectations/cpp_monos +++ b/twiggy/tests/expectations/cpp_monos @@ -1,6 +1,7 @@ Apprx. Bloat Bytes │ Apprx. Bloat % │ Bytes │ % │ Monomorphizations ────────────────────┼────────────────┼───────┼───────┼───────────────────────── 14 ┊ 3.01% ┊ 21 ┊ 4.52% ┊ void generic - ┊ ┊ 7 ┊ 1.51% ┊ void generic() ┊ ┊ 7 ┊ 1.51% ┊ void generic() ┊ ┊ 7 ┊ 1.51% ┊ void generic() + ┊ ┊ 7 ┊ 1.51% ┊ void generic() + 14 ┊ 3.01% ┊ 21 ┊ 4.52% ┊ Σ [4 Total Rows] diff --git a/twiggy/tests/expectations/monos b/twiggy/tests/expectations/monos index efa887ea..f248d1f7 100644 --- a/twiggy/tests/expectations/monos +++ b/twiggy/tests/expectations/monos @@ -1,50 +1,52 @@ - Apprx. Bloat Bytes │ Apprx. Bloat % │ Bytes │ % │ Monomorphizations -────────────────────┼────────────────┼───────┼───────┼──────────────────────────────────────────────────────────────────────────────────────────────────── - 1977 ┊ 3.40% ┊ 3003 ┊ 5.16% ┊ alloc::slice::merge_sort - ┊ ┊ 1026 ┊ 1.76% ┊ alloc::slice::merge_sort::hb3d195f9800bdad6 - ┊ ┊ 1026 ┊ 1.76% ┊ alloc::slice::merge_sort::hfcf2318d7dc71d03 - ┊ ┊ 951 ┊ 1.63% ┊ alloc::slice::merge_sort::hcfca67f5c75a52ef - 1302 ┊ 2.24% ┊ 3996 ┊ 6.87% ┊ <&'a T as core::fmt::Debug>::fmt - ┊ ┊ 2694 ┊ 4.63% ┊ <&'a T as core::fmt::Debug>::fmt::h1c27955d8de3ff17 - ┊ ┊ 568 ┊ 0.98% ┊ <&'a T as core::fmt::Debug>::fmt::hea6a77c4dcddb7ac - ┊ ┊ 433 ┊ 0.74% ┊ <&'a T as core::fmt::Debug>::fmt::hfbacf6f5c9f53bb2 - ┊ ┊ 301 ┊ 0.52% ┊ <&'a T as core::fmt::Debug>::fmt::h199e8e1c5752e6f1 - 973 ┊ 1.67% ┊ 1118 ┊ 1.92% ┊ core::result::unwrap_failed - ┊ ┊ 145 ┊ 0.25% ┊ core::result::unwrap_failed::h9bd27c3a9ad7c001 - ┊ ┊ 145 ┊ 0.25% ┊ core::result::unwrap_failed::h4cc73eb9bf19ce32 - ┊ ┊ 145 ┊ 0.25% ┊ core::result::unwrap_failed::h137aa4f433aba1a9 - ┊ ┊ 138 ┊ 0.24% ┊ core::result::unwrap_failed::ha3e58cfc7f422ab4 - ┊ ┊ 138 ┊ 0.24% ┊ core::result::unwrap_failed::h9a7678774db14d67 - ┊ ┊ 138 ┊ 0.24% ┊ core::result::unwrap_failed::hcb258ce32bda3d85 - ┊ ┊ 138 ┊ 0.24% ┊ core::result::unwrap_failed::ha7651fcaac40f701 - ┊ ┊ 131 ┊ 0.23% ┊ core::result::unwrap_failed::hcfddf900474e698a - 558 ┊ 0.96% ┊ 714 ┊ 1.23% ┊ >::double - ┊ ┊ 156 ┊ 0.27% ┊ >::double::h28f86621ee2a10aa - ┊ ┊ 156 ┊ 0.27% ┊ >::double::h956450b93bdc9e1e - ┊ ┊ 156 ┊ 0.27% ┊ >::double::hcb2fb5861b96a3b0 - ┊ ┊ 147 ┊ 0.25% ┊ >::double::ha715b4e5cc3c60ae - ┊ ┊ 99 ┊ 0.17% ┊ >::double::h77ff8547127c5db2 - 512 ┊ 0.88% ┊ 798 ┊ 1.37% ┊ std::thread::local::os::destroy_value - ┊ ┊ 286 ┊ 0.49% ┊ std::thread::local::os::destroy_value::hca8124786bee4a79 - ┊ ┊ 281 ┊ 0.48% ┊ std::thread::local::os::destroy_value::h094cf4f2a025ba2b - ┊ ┊ 231 ┊ 0.40% ┊ std::thread::local::os::destroy_value::h453d41f6c315da32 - 234 ┊ 0.40% ┊ 354 ┊ 0.61% ┊ alloc::slice::insert_head - ┊ ┊ 120 ┊ 0.21% ┊ alloc::slice::insert_head::haf6e08236bab8bde - ┊ ┊ 120 ┊ 0.21% ┊ alloc::slice::insert_head::h2cdb84a455761146 - ┊ ┊ 114 ┊ 0.20% ┊ alloc::slice::insert_head::hed0e79da03eeec8b - 196 ┊ 0.34% ┊ 294 ┊ 0.51% ┊ as core::fmt::Write>::write_fmt - ┊ ┊ 98 ┊ 0.17% ┊ as core::fmt::Write>::write_fmt::h1b74a5fafe15c8eb - ┊ ┊ 98 ┊ 0.17% ┊ as core::fmt::Write>::write_fmt::h24034d1c07bfae93 - ┊ ┊ 98 ┊ 0.17% ┊ as core::fmt::Write>::write_fmt::h5ebed3e159974658 - 195 ┊ 0.34% ┊ 270 ┊ 0.46% ┊ >::push - ┊ ┊ 75 ┊ 0.13% ┊ >::push::h98b02eda22d1ca25 - ┊ ┊ 66 ┊ 0.11% ┊ >::push::hc927b4bedb35b00d - ┊ ┊ 66 ┊ 0.11% ┊ >::push::h5729b9e7651ef67b - ┊ ┊ 63 ┊ 0.11% ┊ >::push::h9415ef699ccc65d8 - 119 ┊ 0.20% ┊ 180 ┊ 0.31% ┊ as core::slice::SliceIndex<[T]>>::index_mut - ┊ ┊ 61 ┊ 0.10% ┊ as core::slice::SliceIndex<[T]>>::index_mut::hba42cce6d0c0099b - ┊ ┊ 61 ┊ 0.10% ┊ as core::slice::SliceIndex<[T]>>::index_mut::hbf8fcfe76c1f6657 - ┊ ┊ 58 ┊ 0.10% ┊ as core::slice::SliceIndex<[T]>>::index_mut::h1c053f01b6f95d93 - 95 ┊ 0.16% ┊ 190 ┊ 0.33% ┊ core::fmt::Write::write_fmt - ┊ ┊ 95 ┊ 0.16% ┊ core::fmt::Write::write_fmt::ha5ae3249cacba520 - ┊ ┊ 95 ┊ 0.16% ┊ core::fmt::Write::write_fmt::hef4632e1398f5ac8 + Apprx. Bloat Bytes │ Apprx. Bloat % │ Bytes │ % │ Monomorphizations +────────────────────┼────────────────┼───────┼────────┼──────────────────────────────────────────────────────────────────────────────────────────────────── + 1977 ┊ 3.40% ┊ 3003 ┊ 5.16% ┊ alloc::slice::merge_sort + ┊ ┊ 1026 ┊ 1.76% ┊ alloc::slice::merge_sort::hb3d195f9800bdad6 + ┊ ┊ 1026 ┊ 1.76% ┊ alloc::slice::merge_sort::hfcf2318d7dc71d03 + ┊ ┊ 951 ┊ 1.63% ┊ alloc::slice::merge_sort::hcfca67f5c75a52ef + 1302 ┊ 2.24% ┊ 3996 ┊ 6.87% ┊ <&'a T as core::fmt::Debug>::fmt + ┊ ┊ 2694 ┊ 4.63% ┊ <&'a T as core::fmt::Debug>::fmt::h1c27955d8de3ff17 + ┊ ┊ 568 ┊ 0.98% ┊ <&'a T as core::fmt::Debug>::fmt::hea6a77c4dcddb7ac + ┊ ┊ 433 ┊ 0.74% ┊ <&'a T as core::fmt::Debug>::fmt::hfbacf6f5c9f53bb2 + ┊ ┊ 301 ┊ 0.52% ┊ <&'a T as core::fmt::Debug>::fmt::h199e8e1c5752e6f1 + 973 ┊ 1.67% ┊ 1118 ┊ 1.92% ┊ core::result::unwrap_failed + ┊ ┊ 145 ┊ 0.25% ┊ core::result::unwrap_failed::h137aa4f433aba1a9 + ┊ ┊ 145 ┊ 0.25% ┊ core::result::unwrap_failed::h4cc73eb9bf19ce32 + ┊ ┊ 145 ┊ 0.25% ┊ core::result::unwrap_failed::h9bd27c3a9ad7c001 + ┊ ┊ 138 ┊ 0.24% ┊ core::result::unwrap_failed::h9a7678774db14d67 + ┊ ┊ 138 ┊ 0.24% ┊ core::result::unwrap_failed::ha3e58cfc7f422ab4 + ┊ ┊ 138 ┊ 0.24% ┊ core::result::unwrap_failed::ha7651fcaac40f701 + ┊ ┊ 138 ┊ 0.24% ┊ core::result::unwrap_failed::hcb258ce32bda3d85 + ┊ ┊ 131 ┊ 0.23% ┊ core::result::unwrap_failed::hcfddf900474e698a + 558 ┊ 0.96% ┊ 714 ┊ 1.23% ┊ >::double + ┊ ┊ 156 ┊ 0.27% ┊ >::double::h28f86621ee2a10aa + ┊ ┊ 156 ┊ 0.27% ┊ >::double::h956450b93bdc9e1e + ┊ ┊ 156 ┊ 0.27% ┊ >::double::hcb2fb5861b96a3b0 + ┊ ┊ 147 ┊ 0.25% ┊ >::double::ha715b4e5cc3c60ae + ┊ ┊ 99 ┊ 0.17% ┊ >::double::h77ff8547127c5db2 + 512 ┊ 0.88% ┊ 798 ┊ 1.37% ┊ std::thread::local::os::destroy_value + ┊ ┊ 286 ┊ 0.49% ┊ std::thread::local::os::destroy_value::hca8124786bee4a79 + ┊ ┊ 281 ┊ 0.48% ┊ std::thread::local::os::destroy_value::h094cf4f2a025ba2b + ┊ ┊ 231 ┊ 0.40% ┊ std::thread::local::os::destroy_value::h453d41f6c315da32 + 234 ┊ 0.40% ┊ 354 ┊ 0.61% ┊ alloc::slice::insert_head + ┊ ┊ 120 ┊ 0.21% ┊ alloc::slice::insert_head::h2cdb84a455761146 + ┊ ┊ 120 ┊ 0.21% ┊ alloc::slice::insert_head::haf6e08236bab8bde + ┊ ┊ 114 ┊ 0.20% ┊ alloc::slice::insert_head::hed0e79da03eeec8b + 196 ┊ 0.34% ┊ 294 ┊ 0.51% ┊ as core::fmt::Write>::write_fmt + ┊ ┊ 98 ┊ 0.17% ┊ as core::fmt::Write>::write_fmt::h1b74a5fafe15c8eb + ┊ ┊ 98 ┊ 0.17% ┊ as core::fmt::Write>::write_fmt::h24034d1c07bfae93 + ┊ ┊ 98 ┊ 0.17% ┊ as core::fmt::Write>::write_fmt::h5ebed3e159974658 + 195 ┊ 0.34% ┊ 270 ┊ 0.46% ┊ >::push + ┊ ┊ 75 ┊ 0.13% ┊ >::push::h98b02eda22d1ca25 + ┊ ┊ 66 ┊ 0.11% ┊ >::push::h5729b9e7651ef67b + ┊ ┊ 66 ┊ 0.11% ┊ >::push::hc927b4bedb35b00d + ┊ ┊ 63 ┊ 0.11% ┊ >::push::h9415ef699ccc65d8 + 119 ┊ 0.20% ┊ 180 ┊ 0.31% ┊ as core::slice::SliceIndex<[T]>>::index_mut + ┊ ┊ 61 ┊ 0.10% ┊ as core::slice::SliceIndex<[T]>>::index_mut::hba42cce6d0c0099b + ┊ ┊ 61 ┊ 0.10% ┊ as core::slice::SliceIndex<[T]>>::index_mut::hbf8fcfe76c1f6657 + ┊ ┊ 58 ┊ 0.10% ┊ as core::slice::SliceIndex<[T]>>::index_mut::h1c053f01b6f95d93 + 95 ┊ 0.16% ┊ 190 ┊ 0.33% ┊ core::fmt::Write::write_fmt + ┊ ┊ 95 ┊ 0.16% ┊ core::fmt::Write::write_fmt::ha5ae3249cacba520 + ┊ ┊ 95 ┊ 0.16% ┊ core::fmt::Write::write_fmt::hef4632e1398f5ac8 + 298 ┊ 0.51% ┊ 24063 ┊ 41.34% ┊ ... and 187 more. + 6459 ┊ 11.10% ┊ 34980 ┊ 60.10% ┊ Σ [235 Total Rows] diff --git a/twiggy/tests/expectations/monos_json b/twiggy/tests/expectations/monos_json index 636261d9..b2d2b062 100644 --- a/twiggy/tests/expectations/monos_json +++ b/twiggy/tests/expectations/monos_json @@ -1 +1 @@ -[{"generic":"alloc::slice::merge_sort","approximate_monomorphization_bloat_bytes":1977,"approximate_monomorphization_bloat_percent":3.396673768125902,"total_size":3003,"total_size_percent":5.159439213799739,"monomorphizations":[{"name":"alloc::slice::merge_sort::hb3d195f9800bdad6","shallow_size":1026,"shallow_size_percent":1.7627654456738369}]},{"generic":"<&'a T as core::fmt::Debug>::fmt","approximate_monomorphization_bloat_bytes":1302,"approximate_monomorphization_bloat_percent":2.2369596591299565,"total_size":3996,"total_size_percent":6.865507525255995,"monomorphizations":[{"name":"<&'a T as core::fmt::Debug>::fmt::h1c27955d8de3ff17","shallow_size":2694,"shallow_size_percent":4.6285478661260395}]}] +[{"generic":"alloc::slice::merge_sort","approximate_monomorphization_bloat_bytes":1977,"approximate_monomorphization_bloat_percent":3.396673768125902,"total_size":3003,"total_size_percent":5.159439213799739,"monomorphizations":[{"name":"alloc::slice::merge_sort::hb3d195f9800bdad6","shallow_size":1026,"shallow_size_percent":1.7627654456738369},{"name":"... and 2 more.","shallow_size":1977,"shallow_size_percent":3.396673768125902}]},{"generic":"<&'a T as core::fmt::Debug>::fmt","approximate_monomorphization_bloat_bytes":1302,"approximate_monomorphization_bloat_percent":2.2369596591299565,"total_size":3996,"total_size_percent":6.865507525255995,"monomorphizations":[{"name":"<&'a T as core::fmt::Debug>::fmt::h1c27955d8de3ff17","shallow_size":2694,"shallow_size_percent":4.6285478661260395},{"name":"... and 3 more.","shallow_size":1302,"shallow_size_percent":2.2369596591299565}]},{"generic":"... and 196 more.","approximate_monomorphization_bloat_bytes":3180,"approximate_monomorphization_bloat_percent":5.46354202460312,"total_size":27981,"total_size_percent":48.07401553157858,"monomorphizations":[]},{"generic":"Σ [202 Total Rows]","approximate_monomorphization_bloat_bytes":6459,"approximate_monomorphization_bloat_percent":11.097175451858979,"total_size":34980,"total_size_percent":60.09896227063432,"monomorphizations":[]}] diff --git a/twiggy/tests/expectations/monos_maxes b/twiggy/tests/expectations/monos_maxes index 1a0dcf56..ad590a73 100644 --- a/twiggy/tests/expectations/monos_maxes +++ b/twiggy/tests/expectations/monos_maxes @@ -1,6 +1,10 @@ - Apprx. Bloat Bytes │ Apprx. Bloat % │ Bytes │ % │ Monomorphizations -────────────────────┼────────────────┼───────┼───────┼──────────────────────────────────────────────────────── - 1977 ┊ 3.40% ┊ 3003 ┊ 5.16% ┊ alloc::slice::merge_sort - ┊ ┊ 1026 ┊ 1.76% ┊ alloc::slice::merge_sort::hb3d195f9800bdad6 - 1302 ┊ 2.24% ┊ 3996 ┊ 6.87% ┊ <&'a T as core::fmt::Debug>::fmt - ┊ ┊ 2694 ┊ 4.63% ┊ <&'a T as core::fmt::Debug>::fmt::h1c27955d8de3ff17 +Apprx. Bloat Bytes │ Apprx. Bloat % │ Bytes │ % │ Monomorphizations +────────────────────┼────────────────┼───────┼────────┼──────────────────────────────────────────────────────── + 1977 ┊ 3.40% ┊ 3003 ┊ 5.16% ┊ alloc::slice::merge_sort + ┊ ┊ 1026 ┊ 1.76% ┊ alloc::slice::merge_sort::hb3d195f9800bdad6 + ┊ ┊ 1977 ┊ 3.40% ┊ ... and 2 more. + 1302 ┊ 2.24% ┊ 3996 ┊ 6.87% ┊ <&'a T as core::fmt::Debug>::fmt + ┊ ┊ 2694 ┊ 4.63% ┊ <&'a T as core::fmt::Debug>::fmt::h1c27955d8de3ff17 + ┊ ┊ 1302 ┊ 2.24% ┊ ... and 3 more. + 3180 ┊ 5.46% ┊ 27981 ┊ 48.07% ┊ ... and 196 more. + 6459 ┊ 11.10% ┊ 34980 ┊ 60.10% ┊ Σ [202 Total Rows] diff --git a/twiggy/tests/expectations/monos_only_generics b/twiggy/tests/expectations/monos_only_generics index 580b7eda..e2b9eb13 100644 --- a/twiggy/tests/expectations/monos_only_generics +++ b/twiggy/tests/expectations/monos_only_generics @@ -1,12 +1,14 @@ - Apprx. Bloat Bytes │ Apprx. Bloat % │ Bytes │ % │ Monomorphizations -────────────────────┼────────────────┼───────┼───────┼───────────────────────────────────────────────────────────────────────────── - 1977 ┊ 3.40% ┊ 3003 ┊ 5.16% ┊ alloc::slice::merge_sort - 1302 ┊ 2.24% ┊ 3996 ┊ 6.87% ┊ <&'a T as core::fmt::Debug>::fmt - 973 ┊ 1.67% ┊ 1118 ┊ 1.92% ┊ core::result::unwrap_failed - 558 ┊ 0.96% ┊ 714 ┊ 1.23% ┊ >::double - 512 ┊ 0.88% ┊ 798 ┊ 1.37% ┊ std::thread::local::os::destroy_value - 234 ┊ 0.40% ┊ 354 ┊ 0.61% ┊ alloc::slice::insert_head - 196 ┊ 0.34% ┊ 294 ┊ 0.51% ┊ as core::fmt::Write>::write_fmt - 195 ┊ 0.34% ┊ 270 ┊ 0.46% ┊ >::push - 119 ┊ 0.20% ┊ 180 ┊ 0.31% ┊ as core::slice::SliceIndex<[T]>>::index_mut - 95 ┊ 0.16% ┊ 190 ┊ 0.33% ┊ core::fmt::Write::write_fmt + Apprx. Bloat Bytes │ Apprx. Bloat % │ Bytes │ % │ Monomorphizations +────────────────────┼────────────────┼───────┼────────┼───────────────────────────────────────────────────────────────────────────── + 1977 ┊ 3.40% ┊ 3003 ┊ 5.16% ┊ alloc::slice::merge_sort + 1302 ┊ 2.24% ┊ 3996 ┊ 6.87% ┊ <&'a T as core::fmt::Debug>::fmt + 973 ┊ 1.67% ┊ 1118 ┊ 1.92% ┊ core::result::unwrap_failed + 558 ┊ 0.96% ┊ 714 ┊ 1.23% ┊ >::double + 512 ┊ 0.88% ┊ 798 ┊ 1.37% ┊ std::thread::local::os::destroy_value + 234 ┊ 0.40% ┊ 354 ┊ 0.61% ┊ alloc::slice::insert_head + 196 ┊ 0.34% ┊ 294 ┊ 0.51% ┊ as core::fmt::Write>::write_fmt + 195 ┊ 0.34% ┊ 270 ┊ 0.46% ┊ >::push + 119 ┊ 0.20% ┊ 180 ┊ 0.31% ┊ as core::slice::SliceIndex<[T]>>::index_mut + 95 ┊ 0.16% ┊ 190 ┊ 0.33% ┊ core::fmt::Write::write_fmt + 298 ┊ 0.51% ┊ 24063 ┊ 41.34% ┊ ... and 81 more. + 6459 ┊ 11.10% ┊ 34980 ┊ 60.10% ┊ Σ [91 Total Rows] diff --git a/twiggy/tests/expectations/monos_wasm_csv b/twiggy/tests/expectations/monos_wasm_csv index d3d3b173..3d54730e 100644 --- a/twiggy/tests/expectations/monos_wasm_csv +++ b/twiggy/tests/expectations/monos_wasm_csv @@ -1,11 +1,13 @@ Generic,ApproximateMonomorphizationBloatBytes,ApproximateMonomorphizationBloatPercent,TotalSize,TotalSizePercent,Monomorphizations alloc::slice::merge_sort,1977,3.396673768125902,3003,5.159439213799739,"alloc::slice::merge_sort::hb3d195f9800bdad6, alloc::slice::merge_sort::hfcf2318d7dc71d03, alloc::slice::merge_sort::hcfca67f5c75a52ef" <&'a T as core::fmt::Debug>::fmt,1302,2.2369596591299565,3996,6.865507525255995,"<&'a T as core::fmt::Debug>::fmt::h1c27955d8de3ff17, <&'a T as core::fmt::Debug>::fmt::hea6a77c4dcddb7ac, <&'a T as core::fmt::Debug>::fmt::hfbacf6f5c9f53bb2, <&'a T as core::fmt::Debug>::fmt::h199e8e1c5752e6f1" -core::result::unwrap_failed,973,1.6717064119304514,1118,1.9208301834925434,"core::result::unwrap_failed::h9bd27c3a9ad7c001, core::result::unwrap_failed::h4cc73eb9bf19ce32, core::result::unwrap_failed::h137aa4f433aba1a9, core::result::unwrap_failed::ha3e58cfc7f422ab4, core::result::unwrap_failed::h9a7678774db14d67, core::result::unwrap_failed::hcb258ce32bda3d85, core::result::unwrap_failed::ha7651fcaac40f701, core::result::unwrap_failed::hcfddf900474e698a" +core::result::unwrap_failed,973,1.6717064119304514,1118,1.9208301834925434,"core::result::unwrap_failed::h137aa4f433aba1a9, core::result::unwrap_failed::h4cc73eb9bf19ce32, core::result::unwrap_failed::h9bd27c3a9ad7c001, core::result::unwrap_failed::h9a7678774db14d67, core::result::unwrap_failed::ha3e58cfc7f422ab4, core::result::unwrap_failed::ha7651fcaac40f701, core::result::unwrap_failed::hcb258ce32bda3d85, core::result::unwrap_failed::hcfddf900474e698a" ">::double",558,0.9586969967699815,714,1.2267198130712667,">::double::h28f86621ee2a10aa, >::double::h956450b93bdc9e1e, >::double::hcb2fb5861b96a3b0, >::double::ha715b4e5cc3c60ae, >::double::h77ff8547127c5db2" std::thread::local::os::destroy_value,512,0.8796646278606282,798,1.3710397910796508,"std::thread::local::os::destroy_value::hca8124786bee4a79, std::thread::local::os::destroy_value::h094cf4f2a025ba2b, std::thread::local::os::destroy_value::h453d41f6c315da32" -alloc::slice::insert_head,234,0.4020342244519277,354,0.6082056216067624,"alloc::slice::insert_head::haf6e08236bab8bde, alloc::slice::insert_head::h2cdb84a455761146, alloc::slice::insert_head::hed0e79da03eeec8b" +alloc::slice::insert_head,234,0.4020342244519277,354,0.6082056216067624,"alloc::slice::insert_head::h2cdb84a455761146, alloc::slice::insert_head::haf6e08236bab8bde, alloc::slice::insert_head::hed0e79da03eeec8b" " as core::fmt::Write>::write_fmt",196,0.33674661535289674,294,0.505119923029345," as core::fmt::Write>::write_fmt::h1b74a5fafe15c8eb, as core::fmt::Write>::write_fmt::h24034d1c07bfae93, as core::fmt::Write>::write_fmt::h5ebed3e159974658" ->::push,195,0.3350285203766064,270,0.46388564359837814,">::push::h98b02eda22d1ca25, >::push::hc927b4bedb35b00d, >::push::h5729b9e7651ef67b, >::push::h9415ef699ccc65d8" +>::push,195,0.3350285203766064,270,0.46388564359837814,">::push::h98b02eda22d1ca25, >::push::h5729b9e7651ef67b, >::push::hc927b4bedb35b00d, >::push::h9415ef699ccc65d8" as core::slice::SliceIndex<[T]>>::index_mut,119,0.20445330217854443,180,0.3092570957322521," as core::slice::SliceIndex<[T]>>::index_mut::hba42cce6d0c0099b, as core::slice::SliceIndex<[T]>>::index_mut::hbf8fcfe76c1f6657, as core::slice::SliceIndex<[T]>>::index_mut::h1c053f01b6f95d93" core::fmt::Write::write_fmt,95,0.1632190227475775,190,0.326438045495155,"core::fmt::Write::write_fmt::ha5ae3249cacba520, core::fmt::Write::write_fmt::hef4632e1398f5ac8" +... and 187 more.,298,0.5119923029345063,24063,41.34251941447323, +Σ [235 Total Rows],6459,11.097175451858979,34980,60.09896227063432,