From fd13da1f5c23398a36775205a431de51aac92dd7 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 17 Dec 2023 12:05:39 -0500 Subject: [PATCH] Avoid extra allocations while generating HTML reports --- src/assets.rs | 4 +- src/report/display.rs | 2 +- src/report/html.rs | 150 +++++++++++++++++++++------------- templates/macros.html | 6 +- templates/report/results.html | 27 ++---- 5 files changed, 109 insertions(+), 80 deletions(-) diff --git a/src/assets.rs b/src/assets.rs index fc66d833..c2ba848e 100644 --- a/src/assets.rs +++ b/src/assets.rs @@ -161,5 +161,7 @@ pub fn render_template(name: &str, context: &C) -> Fallible), +enum ReportCratesHTML<'a> { + Plain(Vec>), Tree { count: u32, - tree: IndexMap>, + tree: IndexMap>>, }, RootResults { count: u32, - results: IndexMap>, + results: IndexMap>>, }, } @@ -61,13 +65,13 @@ impl CurrentPage { struct ResultsContext<'a> { ex: &'a Experiment, nav: Vec, - categories: Vec<(Comparison, ReportCratesHTML)>, + // (comparison, category color, ...) + categories: Vec<(Comparison, usize, ReportCratesHTML<'a>)>, info: IndexMap, full: bool, crates_count: usize, - comparison_colors: IndexMap, - result_colors: Vec, - result_names: Vec, + colors: IndexSet, + result_names: IndexSet, } #[derive(Serialize)] @@ -80,20 +84,52 @@ struct DownloadsContext<'a> { } #[derive(Serialize)] -struct CrateResultHTML { - name: String, - url: String, +struct CrateResultHTML<'a> { + name: &'a str, + url: &'a str, res: Comparison, #[serde(skip_serializing_if = "Option::is_none")] - status: Option, - runs: [Option; 2], + status: Option, + color_idx: usize, + runs: [Option>; 2], } // Map TestResult to usize to avoid the presence of special characters in html #[derive(Serialize)] -struct BuildTestResultHTML { - res: usize, - log: String, +struct BuildTestResultHTML<'a> { + color_idx: usize, + name_idx: usize, + log: &'a str, +} + +fn to_html_crate_result<'a>( + colors: &mut IndexSet, + result_names: &mut IndexSet, + category_color: usize, + result: &'a CrateResult, +) -> CrateResultHTML<'a> { + let mut runs = [None, None]; + + for (pos, run) in result.runs.iter().enumerate() { + if let Some(run) = run { + let (color_idx, _) = colors.insert_full(run.res.color()); + let (name_idx, _) = result_names.insert_full(run.res.short_name()); + runs[pos] = Some(BuildTestResultHTML { + color_idx, + name_idx, + log: run.log.as_str(), + }); + } + } + + CrateResultHTML { + name: result.name.as_str(), + url: result.url.as_str(), + status: result.status, + res: result.res, + color_idx: category_color, + runs, + } } fn write_report( @@ -105,54 +141,37 @@ fn write_report( dest: &W, output_templates: bool, ) -> Fallible<()> { - let mut comparison_colors = IndexMap::new(); - let mut test_results_to_int = IndexMap::new(); - let mut result_colors = Vec::new(); - let mut result_names = Vec::new(); + let mut colors = IndexSet::new(); + let mut result_names = IndexSet::new(); - let mut to_html_crate_result = |result: CrateResult| { - let mut runs = [None, None]; - - for (pos, run) in result.runs.iter().enumerate() { - if let Some(ref run) = run { - let idx = test_results_to_int - .entry(run.res.clone()) - .or_insert_with(|| { - result_colors.push(run.res.color()); - result_names.push(run.res.short_name()); - result_names.len() - 1 - }); - runs[pos] = Some(BuildTestResultHTML { - res: *idx, - log: run.log.clone(), - }); - } - } - - CrateResultHTML { - name: result.name.clone(), - url: result.url.clone(), - status: result.status.map(|status| status.to_string()), - res: result.res, - runs, - } - }; + let color_for_category = res + .categories + .keys() + .map(|category| (category.color(), colors.insert_full(category.color()).0)) + .collect::>(); let categories = res .categories .iter() .filter(|(category, _)| full || category.show_in_summary()) - .map(|(&category, crates)| (category, crates.to_owned())) + .map(|(&category, crates)| (category, crates)) .flat_map(|(category, crates)| { - comparison_colors.insert(category, category.color()); - + let category_color_idx = *color_for_category.get(&category.color()).unwrap(); match crates { ReportCrates::Plain(crates) => vec![( category, + category_color_idx, ReportCratesHTML::Plain( crates .into_iter() - .map(|result| to_html_crate_result(result)) + .map(|result| { + to_html_crate_result( + &mut colors, + &mut result_names, + category_color_idx, + result, + ) + }) .collect::>(), ), )] @@ -164,7 +183,14 @@ fn write_report( ( root.to_string(), deps.into_iter() - .map(|result| to_html_crate_result(result)) + .map(|result| { + to_html_crate_result( + &mut colors, + &mut result_names, + category_color_idx, + result, + ) + }) .collect::>(), ) }) @@ -176,7 +202,14 @@ fn write_report( res.long_name(), krates .into_iter() - .map(|result| to_html_crate_result(result)) + .map(|result| { + to_html_crate_result( + &mut colors, + &mut result_names, + category_color_idx, + result, + ) + }) .collect::>(), ) }) @@ -185,6 +218,7 @@ fn write_report( vec![ ( category, + category_color_idx, ReportCratesHTML::Tree { count: tree.keys().len() as u32, tree, @@ -192,6 +226,7 @@ fn write_report( ), ( category, + category_color_idx, ReportCratesHTML::RootResults { count: results.keys().len() as u32, results, @@ -216,13 +251,14 @@ fn write_report( info: res.info.clone(), full, crates_count, - comparison_colors, - result_colors, + colors, result_names, }; info!("generating {}", to); - let html = minifier::html::minify(&assets::render_template("report/results.html", &context)?); + let rendered = assets::render_template("report/results.html", &context) + .context("rendering template report/results.html")?; + let html = minifier::html::minify(&rendered); dest.write_string(to, html.into(), &mime::TEXT_HTML)?; if output_templates { diff --git a/templates/macros.html b/templates/macros.html index a07889ac..e7f26d53 100644 --- a/templates/macros.html +++ b/templates/macros.html @@ -36,10 +36,10 @@ {% for run in crate.runs %} {% if run %} - - {{ result_names[run.res] }} + + {{ result_names[run.name_idx] }} {% else %} - + {{ crate.res }} {% endif %} diff --git a/templates/report/results.html b/templates/report/results.html index 89a470d7..b06fb82a 100644 --- a/templates/report/results.html +++ b/templates/report/results.html @@ -5,18 +5,8 @@ {% block extra_head %}