Skip to content

Commit b0145e1

Browse files
authored
Merge pull request #1281 from rylev/simplify-relevance
Simplify artifact comparison relevance
2 parents f46d4db + 4e505cf commit b0145e1

File tree

2 files changed

+74
-175
lines changed

2 files changed

+74
-175
lines changed

site/src/comparison.rs

Lines changed: 49 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -146,37 +146,37 @@ 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(d), Some(_) | None) => d,
157+
(None, Some(d)) => d,
158+
(None, None) => return,
159+
};
160+
161+
let entry = report.entry(direction).or_default();
162+
163+
entry.push(write_triage_summary(comparison, &primary, &secondary).await)
163164
}
164165

165166
/// A summary of a given comparison
166167
///
167168
/// This summary only includes changes that are significant and relevant (as determined by a change's magnitude).
168169
pub struct ComparisonSummary {
169-
/// Significant comparisons of magnitude small and above
170-
/// and ordered by magnitude from largest to smallest
171-
comparisons: Vec<TestResultComparison>,
170+
/// Relevant comparisons ordered by magnitude from largest to smallest
171+
relevant_comparisons: Vec<TestResultComparison>,
172172
/// The cached number of comparisons that are improvements
173173
num_improvements: usize,
174174
/// The cached number of comparisons that are regressions
175175
num_regressions: usize,
176176
}
177177

178178
impl ComparisonSummary {
179-
pub fn summarize_comparison(comparison: &Comparison) -> Option<Self> {
179+
pub fn summarize_comparison(comparison: &Comparison) -> Self {
180180
let mut num_improvements = 0;
181181
let mut num_regressions = 0;
182182

@@ -193,10 +193,6 @@ impl ComparisonSummary {
193193
})
194194
.cloned()
195195
.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-
}
200196

201197
let cmp = |b1: &TestResultComparison, b2: &TestResultComparison| {
202198
b2.relative_change()
@@ -206,29 +202,23 @@ impl ComparisonSummary {
206202
};
207203
comparisons.sort_by(cmp);
208204

209-
Some(ComparisonSummary {
210-
comparisons,
205+
ComparisonSummary {
206+
relevant_comparisons: comparisons,
211207
num_improvements,
212208
num_regressions,
213-
})
214-
}
215-
216-
pub fn empty() -> Self {
217-
ComparisonSummary {
218-
comparisons: vec![],
219-
num_improvements: 0,
220-
num_regressions: 0,
221209
}
222210
}
223211

224212
/// The direction of the changes
225213
pub fn direction(&self) -> Option<Direction> {
226-
if self.comparisons.len() == 0 {
214+
if self.relevant_comparisons.len() == 0 {
227215
return None;
228216
}
229217

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

233223
if regressions.len() == 0 {
234224
return Some(Direction::Improvement);
@@ -238,7 +228,7 @@ impl ComparisonSummary {
238228
return Some(Direction::Regression);
239229
}
240230

241-
let total_num = self.comparisons.len();
231+
let total_num = self.relevant_comparisons.len();
242232
let regressions_ratio = regressions.len() as f64 / total_num as f64;
243233

244234
let has_medium_and_above_regressions = regressions
@@ -300,18 +290,11 @@ impl ComparisonSummary {
300290

301291
/// Arithmetic mean of all changes as a percent
302292
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()
293+
self.arithmetic_mean(self.relevant_comparisons.iter())
311294
}
312295

313296
pub fn is_empty(&self) -> bool {
314-
self.comparisons.is_empty()
297+
self.relevant_comparisons.is_empty()
315298
}
316299

317300
fn arithmetic_mean<'a>(
@@ -329,45 +312,38 @@ impl ComparisonSummary {
329312
}
330313

331314
fn improvements(&self) -> impl Iterator<Item = &TestResultComparison> {
332-
self.comparisons.iter().filter(|c| c.is_improvement())
315+
self.relevant_comparisons
316+
.iter()
317+
.filter(|c| c.is_improvement())
333318
}
334319

335320
fn regressions(&self) -> impl Iterator<Item = &TestResultComparison> {
336-
self.comparisons.iter().filter(|c| c.is_regression())
321+
self.relevant_comparisons
322+
.iter()
323+
.filter(|c| c.is_regression())
337324
}
338325

339326
fn largest_improvement(&self) -> Option<&TestResultComparison> {
340-
self.comparisons.iter().find(|s| s.is_improvement())
327+
self.relevant_comparisons
328+
.iter()
329+
.find(|s| s.is_improvement())
341330
}
342331

343332
fn largest_regression(&self) -> Option<&TestResultComparison> {
344-
self.comparisons.iter().find(|s| s.is_regression())
333+
self.relevant_comparisons.iter().find(|s| s.is_regression())
345334
}
346335

347336
/// 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-
}
337+
pub fn is_relevant(&self) -> bool {
338+
!self.is_empty()
367339
}
368340
}
369341

370-
async fn write_triage_summary(ctxt: &SiteCtxt, comparison: &Comparison) -> String {
342+
async fn write_triage_summary(
343+
comparison: &Comparison,
344+
primary: &ComparisonSummary,
345+
secondary: &ComparisonSummary,
346+
) -> String {
371347
use std::fmt::Write;
372348
let mut result = if let Some(pr) = comparison.b.pr {
373349
let title = github::pr_title(pr).await;
@@ -383,11 +359,6 @@ async fn write_triage_summary(ctxt: &SiteCtxt, comparison: &Comparison) -> Strin
383359
let link = &compare_link(start, end);
384360
write!(&mut result, " [(Comparison Link)]({})\n", link).unwrap();
385361

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-
391362
write_summary_table(&primary, &secondary, false, &mut result);
392363

393364
result
@@ -506,24 +477,6 @@ pub fn write_summary_table(
506477
}
507478
}
508479

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-
527480
/// Compare two bounds on a given stat
528481
///
529482
/// Returns Ok(None) when no data for the end bound is present
@@ -782,7 +735,7 @@ impl Comparison {
782735
pub fn summarize_by_category(
783736
self,
784737
category_map: HashMap<Benchmark, Category>,
785-
) -> (Option<ComparisonSummary>, Option<ComparisonSummary>) {
738+
) -> (ComparisonSummary, ComparisonSummary) {
786739
let (primary, secondary) = self
787740
.statistics
788741
.into_iter()
@@ -1146,7 +1099,7 @@ impl Magnitude {
11461099
async fn generate_report(
11471100
start: &Bound,
11481101
end: &Bound,
1149-
mut report: HashMap<Option<Direction>, Vec<String>>,
1102+
mut report: HashMap<Direction, Vec<String>>,
11501103
num_comparisons: usize,
11511104
) -> String {
11521105
fn fmt_bound(bound: &Bound) -> String {
@@ -1158,14 +1111,9 @@ async fn generate_report(
11581111
}
11591112
let start = fmt_bound(start);
11601113
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();
1114+
let regressions = report.remove(&Direction::Regression).unwrap_or_default();
1115+
let improvements = report.remove(&Direction::Improvement).unwrap_or_default();
1116+
let mixed = report.remove(&Direction::Mixed).unwrap_or_default();
11691117
let untriaged = match github::untriaged_perf_regressions().await {
11701118
Ok(u) => u
11711119
.iter()
@@ -1205,15 +1153,6 @@ Revision range: [{first_commit}..{last_commit}](https://perf.rust-lang.org/?star
12051153
12061154
{mixed}
12071155
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-
12171156
#### Untriaged Pull Requests
12181157
12191158
{untriaged}
@@ -1233,7 +1172,6 @@ TODO: Nags
12331172
regressions = regressions.join("\n\n"),
12341173
improvements = improvements.join("\n\n"),
12351174
mixed = mixed.join("\n\n"),
1236-
unlabeled = unlabeled.join("\n\n"),
12371175
untriaged = untriaged
12381176
)
12391177
}
@@ -1486,6 +1424,5 @@ mod tests {
14861424
newly_failed_benchmarks: Default::default(),
14871425
};
14881426
ComparisonSummary::summarize_comparison(&comparison)
1489-
.unwrap_or_else(|| ComparisonSummary::empty())
14901427
}
14911428
}

0 commit comments

Comments
 (0)