Skip to content

Commit bbd0ac7

Browse files
committed
Simplify artifact comparison relevance
1 parent f46d4db commit bbd0ac7

File tree

2 files changed

+76
-175
lines changed

2 files changed

+76
-175
lines changed

site/src/comparison.rs

Lines changed: 51 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -146,37 +146,39 @@ pub async fn handle_compare(
146146
async fn populate_report(
147147
ctxt: &SiteCtxt,
148148
comparison: &Comparison,
149-
report: &mut HashMap<Option<Direction>, Vec<String>>,
149+
report: &mut HashMap<Direction, Vec<String>>,
150150
) {
151-
if let Some(summary) = ComparisonSummary::summarize_comparison(comparison) {
152-
let relevance = summary.relevance_level();
153-
if relevance.at_least_somewhat_relevant() {
154-
if let Some(direction) = summary.direction() {
155-
let entry = report
156-
.entry(relevance.very_relevant().then(|| direction))
157-
.or_default();
158-
159-
entry.push(write_triage_summary(ctxt, comparison).await)
160-
}
161-
}
162-
}
151+
let benchmark_map = ctxt.get_benchmark_category_map().await;
152+
let (primary, secondary) = comparison.clone().summarize_by_category(benchmark_map);
153+
// Get the combined direction of the primary and secondary summaries
154+
let direction = match (primary.direction(), secondary.direction()) {
155+
(Some(d1), Some(d2)) if d1 != d2 => Direction::Mixed,
156+
(Some(Direction::Improvement), Some(_) | None) => Direction::Improvement,
157+
(Some(Direction::Regression), Some(_) | None) => Direction::Regression,
158+
(Some(Direction::Mixed), Some(_) | None) => Direction::Mixed,
159+
(None, Some(d)) => d,
160+
(None, None) => return,
161+
};
162+
163+
let entry = report.entry(direction).or_default();
164+
165+
entry.push(write_triage_summary(comparison, &primary, &secondary).await)
163166
}
164167

165168
/// A summary of a given comparison
166169
///
167170
/// This summary only includes changes that are significant and relevant (as determined by a change's magnitude).
168171
pub struct ComparisonSummary {
169-
/// Significant comparisons of magnitude small and above
170-
/// and ordered by magnitude from largest to smallest
171-
comparisons: Vec<TestResultComparison>,
172+
/// Relevant comparisons ordered by magnitude from largest to smallest
173+
relevant_comparisons: Vec<TestResultComparison>,
172174
/// The cached number of comparisons that are improvements
173175
num_improvements: usize,
174176
/// The cached number of comparisons that are regressions
175177
num_regressions: usize,
176178
}
177179

178180
impl ComparisonSummary {
179-
pub fn summarize_comparison(comparison: &Comparison) -> Option<Self> {
181+
pub fn summarize_comparison(comparison: &Comparison) -> Self {
180182
let mut num_improvements = 0;
181183
let mut num_regressions = 0;
182184

@@ -193,10 +195,6 @@ impl ComparisonSummary {
193195
})
194196
.cloned()
195197
.collect::<Vec<_>>();
196-
// Skip empty commits, sometimes happens if there's a compiler bug or so.
197-
if comparisons.len() == 0 {
198-
return None;
199-
}
200198

201199
let cmp = |b1: &TestResultComparison, b2: &TestResultComparison| {
202200
b2.relative_change()
@@ -206,29 +204,23 @@ impl ComparisonSummary {
206204
};
207205
comparisons.sort_by(cmp);
208206

209-
Some(ComparisonSummary {
210-
comparisons,
207+
ComparisonSummary {
208+
relevant_comparisons: comparisons,
211209
num_improvements,
212210
num_regressions,
213-
})
214-
}
215-
216-
pub fn empty() -> Self {
217-
ComparisonSummary {
218-
comparisons: vec![],
219-
num_improvements: 0,
220-
num_regressions: 0,
221211
}
222212
}
223213

224214
/// The direction of the changes
225215
pub fn direction(&self) -> Option<Direction> {
226-
if self.comparisons.len() == 0 {
216+
if self.relevant_comparisons.len() == 0 {
227217
return None;
228218
}
229219

230-
let (regressions, improvements): (Vec<&TestResultComparison>, _) =
231-
self.comparisons.iter().partition(|c| c.is_regression());
220+
let (regressions, improvements): (Vec<&TestResultComparison>, _) = self
221+
.relevant_comparisons
222+
.iter()
223+
.partition(|c| c.is_regression());
232224

233225
if regressions.len() == 0 {
234226
return Some(Direction::Improvement);
@@ -238,7 +230,7 @@ impl ComparisonSummary {
238230
return Some(Direction::Regression);
239231
}
240232

241-
let total_num = self.comparisons.len();
233+
let total_num = self.relevant_comparisons.len();
242234
let regressions_ratio = regressions.len() as f64 / total_num as f64;
243235

244236
let has_medium_and_above_regressions = regressions
@@ -300,18 +292,11 @@ impl ComparisonSummary {
300292

301293
/// Arithmetic mean of all changes as a percent
302294
pub fn arithmetic_mean_of_changes(&self) -> f64 {
303-
self.arithmetic_mean(self.comparisons.iter())
304-
}
305-
306-
pub fn num_significant_changes(&self) -> usize {
307-
self.comparisons
308-
.iter()
309-
.filter(|c| c.is_significant())
310-
.count()
295+
self.arithmetic_mean(self.relevant_comparisons.iter())
311296
}
312297

313298
pub fn is_empty(&self) -> bool {
314-
self.comparisons.is_empty()
299+
self.relevant_comparisons.is_empty()
315300
}
316301

317302
fn arithmetic_mean<'a>(
@@ -329,45 +314,38 @@ impl ComparisonSummary {
329314
}
330315

331316
fn improvements(&self) -> impl Iterator<Item = &TestResultComparison> {
332-
self.comparisons.iter().filter(|c| c.is_improvement())
317+
self.relevant_comparisons
318+
.iter()
319+
.filter(|c| c.is_improvement())
333320
}
334321

335322
fn regressions(&self) -> impl Iterator<Item = &TestResultComparison> {
336-
self.comparisons.iter().filter(|c| c.is_regression())
323+
self.relevant_comparisons
324+
.iter()
325+
.filter(|c| c.is_regression())
337326
}
338327

339328
fn largest_improvement(&self) -> Option<&TestResultComparison> {
340-
self.comparisons.iter().find(|s| s.is_improvement())
329+
self.relevant_comparisons
330+
.iter()
331+
.find(|s| s.is_improvement())
341332
}
342333

343334
fn largest_regression(&self) -> Option<&TestResultComparison> {
344-
self.comparisons.iter().find(|s| s.is_regression())
335+
self.relevant_comparisons.iter().find(|s| s.is_regression())
345336
}
346337

347338
/// The relevance level of the entire comparison
348-
pub fn relevance_level(&self) -> RelevanceLevel {
349-
let mut num_small_changes = 0;
350-
let mut num_medium_changes = 0;
351-
for c in self.comparisons.iter() {
352-
match c.magnitude() {
353-
Magnitude::Small => num_small_changes += 1,
354-
Magnitude::Medium => num_medium_changes += 1,
355-
Magnitude::Large => return RelevanceLevel::High,
356-
Magnitude::VeryLarge => return RelevanceLevel::High,
357-
Magnitude::VerySmall => unreachable!(),
358-
}
359-
}
360-
361-
match (num_small_changes, num_medium_changes) {
362-
(_, m) if m > 1 => RelevanceLevel::High,
363-
(_, 1) => RelevanceLevel::Medium,
364-
(s, 0) if s > 10 => RelevanceLevel::Medium,
365-
_ => RelevanceLevel::Low,
366-
}
339+
pub fn is_relevant(&self) -> bool {
340+
!self.is_empty()
367341
}
368342
}
369343

370-
async fn write_triage_summary(ctxt: &SiteCtxt, comparison: &Comparison) -> String {
344+
async fn write_triage_summary(
345+
comparison: &Comparison,
346+
primary: &ComparisonSummary,
347+
secondary: &ComparisonSummary,
348+
) -> String {
371349
use std::fmt::Write;
372350
let mut result = if let Some(pr) = comparison.b.pr {
373351
let title = github::pr_title(pr).await;
@@ -383,11 +361,6 @@ async fn write_triage_summary(ctxt: &SiteCtxt, comparison: &Comparison) -> Strin
383361
let link = &compare_link(start, end);
384362
write!(&mut result, " [(Comparison Link)]({})\n", link).unwrap();
385363

386-
let benchmark_map = ctxt.get_benchmark_category_map().await;
387-
let (primary, secondary) = comparison.clone().summarize_by_category(benchmark_map);
388-
let primary = primary.unwrap_or_else(ComparisonSummary::empty);
389-
let secondary = secondary.unwrap_or_else(ComparisonSummary::empty);
390-
391364
write_summary_table(&primary, &secondary, false, &mut result);
392365

393366
result
@@ -506,24 +479,6 @@ pub fn write_summary_table(
506479
}
507480
}
508481

509-
/// How relevant a set of test result comparisons are.
510-
#[derive(Clone, Copy, Debug)]
511-
pub enum RelevanceLevel {
512-
Low,
513-
Medium,
514-
High,
515-
}
516-
517-
impl RelevanceLevel {
518-
pub fn very_relevant(self) -> bool {
519-
matches!(self, Self::High)
520-
}
521-
522-
pub fn at_least_somewhat_relevant(self) -> bool {
523-
matches!(self, Self::High | Self::Medium)
524-
}
525-
}
526-
527482
/// Compare two bounds on a given stat
528483
///
529484
/// Returns Ok(None) when no data for the end bound is present
@@ -782,7 +737,7 @@ impl Comparison {
782737
pub fn summarize_by_category(
783738
self,
784739
category_map: HashMap<Benchmark, Category>,
785-
) -> (Option<ComparisonSummary>, Option<ComparisonSummary>) {
740+
) -> (ComparisonSummary, ComparisonSummary) {
786741
let (primary, secondary) = self
787742
.statistics
788743
.into_iter()
@@ -1146,7 +1101,7 @@ impl Magnitude {
11461101
async fn generate_report(
11471102
start: &Bound,
11481103
end: &Bound,
1149-
mut report: HashMap<Option<Direction>, Vec<String>>,
1104+
mut report: HashMap<Direction, Vec<String>>,
11501105
num_comparisons: usize,
11511106
) -> String {
11521107
fn fmt_bound(bound: &Bound) -> String {
@@ -1158,14 +1113,9 @@ async fn generate_report(
11581113
}
11591114
let start = fmt_bound(start);
11601115
let end = fmt_bound(end);
1161-
let regressions = report
1162-
.remove(&Some(Direction::Regression))
1163-
.unwrap_or_default();
1164-
let improvements = report
1165-
.remove(&Some(Direction::Improvement))
1166-
.unwrap_or_default();
1167-
let mixed = report.remove(&Some(Direction::Mixed)).unwrap_or_default();
1168-
let unlabeled = report.remove(&None).unwrap_or_default();
1116+
let regressions = report.remove(&Direction::Regression).unwrap_or_default();
1117+
let improvements = report.remove(&Direction::Improvement).unwrap_or_default();
1118+
let mixed = report.remove(&Direction::Mixed).unwrap_or_default();
11691119
let untriaged = match github::untriaged_perf_regressions().await {
11701120
Ok(u) => u
11711121
.iter()
@@ -1205,15 +1155,6 @@ Revision range: [{first_commit}..{last_commit}](https://perf.rust-lang.org/?star
12051155
12061156
{mixed}
12071157
1208-
#### Probably changed
1209-
1210-
The following is a list of comparisons which *probably* represent real performance changes,
1211-
but we're not 100% sure. Please move things from this category into the categories
1212-
above for changes you think *are* definitely relevant and file an issue for each so that
1213-
we can consider how to change our heuristics.
1214-
1215-
{unlabeled}
1216-
12171158
#### Untriaged Pull Requests
12181159
12191160
{untriaged}
@@ -1233,7 +1174,6 @@ TODO: Nags
12331174
regressions = regressions.join("\n\n"),
12341175
improvements = improvements.join("\n\n"),
12351176
mixed = mixed.join("\n\n"),
1236-
unlabeled = unlabeled.join("\n\n"),
12371177
untriaged = untriaged
12381178
)
12391179
}
@@ -1486,6 +1426,5 @@ mod tests {
14861426
newly_failed_benchmarks: Default::default(),
14871427
};
14881428
ComparisonSummary::summarize_comparison(&comparison)
1489-
.unwrap_or_else(|| ComparisonSummary::empty())
14901429
}
14911430
}

0 commit comments

Comments
 (0)